Chociaż każdy typ jest zgodny Any
, to nie jest takie samo jak bycie uniwersalnym niejawna nadklasą że wszystkie typy dziedziczą.
Podczas przesyłania typu do protokołu tworzysz nową wartość o innej strukturze.Tak na ciąg być typu Any
, musi być fizycznie przekształcona z reprezentacją String
:
sizeof(String) // 24 bytes (on 64-bit, anyway)
do reprezentacji Any
:
sizeof(Any) // 32 bytes, includes some meta data
// about what the type really is
Ponieważ typy wartości odbywa się bezpośrednio w tablicy, tablica miałaby zupełnie inny kształt, więc pod maską kompilator musiałby wykonać równoważnik:
names.map { $0 as Any } // create a new array, with the Any versions
Swift może prawdopodobnie zautomatyzować ten proces dla ciebie (ma to miejsce, jeśli przekazujesz pojedynczą zmienną do funkcji, która zajmuje Any
). Ale osobiście cieszę się, że tak nie jest, wolałbym, żeby było to bardziej wyraźne - przypuśćmy, że twoja tablica była ogromna, to byłoby dużo przetwarzania dzieje się domyślnie pod maską.
Różni się to od kiedy masz tablicę typów referencyjnych, z których wszystkie są wskaźnikami do rzeczywistych danych i tak wszystkie tej samej wielkości, a które nie wymagają transformacji, gdy upcasting:
class C { }
class D: C { }
let d = D()
let c: C = d
unsafeBitCast(d, UnsafePointer<Void>.self) // these value will
unsafeBitCast(c, UnsafePointer<Void>.self) // be the same
sposób mówić „ta tablica [D]
jest naprawdę tablicą [C]
” to tylko kwestia kompilatora akceptującej typy mogą być podstawione, transformacja danych nie musi odbywać się:
// so this works fine,
// no runtime transformation needed:
func f(cs: [C]) { }
let ds = [D(),D()]
f(ds)
Ale protokoły nadal różnią się od nadklasy odniesienia w przypadku korzystania z zajęć:
protocol P { }
extension C: P { }
sizeofValue(C()) // 8 bytes (just a pointer)
sizeofValue(C() as P) // 40 bytes
func g(ps: [P]) { }
g(ds) // won’t compile, needs transformation
kciuki za nazwisk w tablicy :) –
nie mogę mówić za szybki, ale w większości języków to może być problem, ponieważ 'printItems' może wziąć tę tablicę' Any' i zmień jeden z elementów na - cóż - wszystko, czego chciał (coś innego niż ciąg znaków). Ale wywołujący myśli, że ma tablicę 'Strings', więc może mieć problemy, gdy skończy się' printItems'. Czy to dotyczy szybkiego? –
Co się stanie, jeśli zmienisz typ tablicy nazw na "[Any]" –