Ten problem wydaje się sugerować, że to tylko szczegół implementacji (w memcpy
porównaniu z ???), ale nie mogę znaleźć żadnego wyraźnego opisu różnic.
129
Ten problem wydaje się sugerować, że to tylko szczegół implementacji (w memcpy
porównaniu z ???), ale nie mogę znaleźć żadnego wyraźnego opisu różnic.
Odpowiedzi:
Clone
jest przeznaczony do dowolnych duplikatów:Clone
implementacja typuT
może wykonywać dowolnie skomplikowane operacje wymagane do utworzenia nowegoT
. Jest to normalna cecha (inna niż bycie w preludium) i dlatego wymaga używania jak normalnej cechy, z wywołaniami metod itp.Copy
Cecha reprezentuje wartości, które mogą być bezpiecznie powielane poprzezmemcpy
: rzeczy jak nadpisywaniem i przechodzącej argumentu przez wartość do funkcji są zawszememcpy
s, a więc dlaCopy
typów, kompilator wie, że nie musi brać pod uwagę ruch .źródło
Clone
jest to głęboka kopia i czyCopy
jest to kopia w tle?Clone
otwiera możliwość, że typ może wykonać głęboką lub płytką kopię: „dowolnie skomplikowane”.Główna różnica polega na tym, że klonowanie jest jawne. Notacja niejawna oznacza ruch dla typu innego niż
Copy
typ.Nawiasem mówiąc, każdy
Copy
typ też musi byćClone
. Jednak nie muszą robić tego samego! W przypadku własnych typów.clone()
może to być dowolna metoda, którą wybierzesz, podczas gdy niejawne kopiowanie zawsze wyzwoli amemcpy
, a nieclone(&self)
implementację.źródło
y
uzyskać przeniesieniex
, a nie jego kopię, jak w przypadku ostatniego zakomentowanego przykładuw = v
. Jak byś to określił?Copy
ma być zaimplementowany dla „tanich” typów, jaku8
w przykładzie. Jeśli piszesz dość ciężki typ, dla którego uważasz, że ruch jest bardziej efektywny niż kopia, nie sugeruj się tymCopy
. Zauważ, że w przypadku u8 nie można być bardziej wydajnym z ruchem, ponieważ pod maską prawdopodobnie wiązałoby się to przynajmniej z kopią wskaźnika - która jest już tak droga jak kopia u8, więc po co zawracać sobie głowę.Copy
cechy ma wpływ na ukryte zakresy zmiennych w czasie życia? Jeśli tak, myślę, że jest to godne uwagi.Jak już opisano w innych odpowiedziach:
Copy
jest niejawny, niedrogi i nie może być ponownie zaimplementowany (memcpy).Clone
jest jawna, może być kosztowna i może zostać dowolnie ponownie wdrożona.To, czego czasami brakuje w dyskusji o
Copy
vs,Clone
to to, że wpływa on również na to, jak kompilator używa ruchów w porównaniu z automatycznymi kopiami. Na przykład:Pierwszy przykład (
PointCloneAndCopy
) działa tutaj dobrze ze względu na niejawną kopię, ale drugi przykład (PointCloneOnly
) spowodowałby błąd przy użyciu po przeniesieniu:Aby uniknąć niejawnego ruchu, możemy jawnie wywołać
let p2 = p1.clone();
.Może to rodzić pytanie, jak wymusić ruch typu, który implementuje cechę Copy? . Krótka odpowiedź: nie możesz / nie ma sensu.
źródło