zmienna pętli for/w pętli kopię wartości utrzymywanej w pojemniku, na której koło się iteracyjnie.
Ponieważ nie można zastąpić domyślnego modułu wyliczającego dla tablic dynamicznych, nie ma możliwości utworzenia modułu wyliczającego, który zwraca odwołania zamiast kopii. Jeśli chcesz zawrzeć tablicę wewnątrz rekordu, możesz utworzyć moduł wyliczający dla rekordu, który będzie zwracał odwołania.
Oczywiście możesz użyć tradycyjnej indeksowanej pętli for, jeśli chcesz uniknąć wykonywania kopii.
Ktoś mógłby zapytać, ponieważ wydaje się, że brak dokumentacji powyższego zestawienia, dlaczego kompilator nie zdecydować się na wprowadzenie takich do/z pętli przy użyciu odwołań zamiast kopii. Tylko projektanci mogą na to odpowiedzieć, ale mogę przedstawić uzasadnienie.
Należy rozważyć niestandardowy moduł wyliczający. documentation opisuje mechanizm następująco:
Aby użyć do pętli w skonstruować na klasę lub interfejsu, klasa lub interfejs musi wdrażać ustaloną wzór zbierania. typ, który implementuje wzorzec zbiórki musi mieć następujące atrybuty:
- Klasa lub interfejs musi zawierać publiczną metodę instancji o nazwie
GetEnumerator()
. Metoda GetEnumerator()
musi zwracać interfejs klasy, lub typ rekordu.
- Klasa, interfejs lub rekord zwrócony przez
GetEnumerator()
musi zawierać publiczną instancję o nazwie MoveNext()
. Metoda MoveNext()
musi zwrócić wartość Boolean
. Pętla for-in wywołuje tę metodę najpierw, aby upewnić się, że pojemnik nie jest pusty.
- Klasa, interfejs lub rekord zwrócony przez
GetEnumerator()
musi zawierać instancję publiczną, właściwość tylko do odczytu o nazwie Current
. Typ właściwości Current
musi być typem z kolekcji .
Zwyczaj wyliczający zwraca każdą wartość z kolekcji poprzez właściwość Current
. A to oznacza, że wartość jest kopiowana.
Oznacza to, że niestandardowe moduły wyliczające zawsze używają kopii.Wyobraź sobie, że wbudowany moduł wyliczający tablice może używać referencji. Oznaczałoby to znaczną różnicę semantyczną między dwoma typami enumeratorów. Na pewno jest prawdopodobne, że projektanci zdecydowali się na spójność między semantyką typów różnicowych: enumeratorów:
W każdym razie zaimplementowałem wskaźniki rekordów dla podobnych scenariuszy. Za każdym razem, gdy chcesz przekazać rekordy i zmodyfikować ich zawartość w różnych miejscach, rekordowy wskaźnik 'PSomeRecord' działa o wiele wydajniej i nie musisz się martwić, że zostanie skopiowany. Zwłaszcza jeśli zawiera dużo treści (dużo pamięci). –
@Jerry Ale teraz musisz zarządzać życiem jawnie –
@David True, to duża zmiana w sposobie, w jaki wszystko działa, ale tak jak powiedziałem, jeśli pojedynczy rekord pochłania dużą ilość pamięci, najlepiej zachować je w wskaźnikach. –