2013-04-25 10 views
16

W Delphi XE4 dla platformy iOS wprowadzono nowy typ łańcucha: niezmienne łańcuchy bazujące na zera. Do tej pory Delphi miał kopię na pisanie łańcuchów zmiennych. Pytanie brzmi: co to oznacza dla mojego przyszłego programowania? Czy istnieją zalety jednego typu ciągów nad drugim? Jakie pułapki muszę załatwić przy przejściu na nowy typ łańcucha (Inny niż oczywiste podstawy 0 vs 1)?Delphi niezmienne struny XE4

+0

Należy zauważyć, że jest to przełącznik kompilacji, jeśli łańcuchy są oparte na zera. Z pewnością nie jest to dobry pomysł na połączenie obu sposobów, ale przynajmniej możesz sam zdecydować, kiedy dokonać przejścia. – jpfollenius

+0

Powinniśmy używać klasy 'TStringBuilder' do manipulacji ciągami i' TStringHelper' do ogólnego zarządzania ciągami znaków. –

+0

Sam typ łańcucha "String" jest w rzeczywistości taki sam jak wcześniej, dotyczy tylko operatora '[]'. Niezmienność oznacza po prostu, że kompilator nie zezwala na przypisanie operatorowi znaku "Char", a dyrektywa '{$ ZEROBASEDSTRINGS}' wpływa tylko na to, jak kompilator interpretuje indeksy przekazywane operatorowi. Sam typ "String" nie został przeprojektowany. –

Odpowiedz

17

Zgodnie z Marco Cantù's whitepaper, typ danych string w celu XE4 iOS nie jest w rzeczywistości niezmienny, chociaż wydaje się zaprzeczać sobie.

Mówi:

W nowym kompilator Delphi LLVM z siedzibą w, jest jeden typ string, reprezentujących ciągi Unicode (UTF16) i przyporządkowuje się do bieżącego typu string w Delphi XE3 (alias Typ UnicodeString w kompilatorze Windows). Jednak ten nowy typ łańcucha używa innego modelu zarządzania pamięcią. Typ łańcucha jest nadal liczony, ale jest niezmienny, co oznacza, że ​​nie można modyfikować zawartości ciągu po jego skonstruowaniu.

Ale potem mówi dalej:

Innymi słowy łańcuchy są teraz Unicode opartych wkrótce stać niezmienne, a odniesienia liczone.

A także:

gdzie wszystko zaczyna się zmieniać, jednak po zmodyfikowaniu istniejącego ciąg, nie zastępując ją nową wartość (w tym przypadku dostaniesz nowy string), ale po zmodyfikowaniu jednego z jego elementów, jak pokazano na tej linii kodu (a także w poprzednim punkcie, gdzie wprowadzony wątek):

Str1 [3] := 'x'; 

Wszystkie kompilatory Delphi używają semantyki kopiowania przy zapisie: Jeśli ciąg znaków, który użytkownik modyfikuje, ma więcej niż jedno odwołanie, jest on najpierw kopiowany (dostosowuje liczby odwołań do różnych wymaganych łańcuchów) i później zmodyfikowany .

Nowy kompilator robi coś bardzo podobnego do klasycznego. To implementuje mechanizm kopiowania przy zapisie, o ile nie ma pojedynczego odwołania do ciągu znaków , w którym to przypadku ciąg jest modyfikowany w miejscu . Jako przykład weź pod uwagę następujący kod, który wyprowadza w pamięci rzeczywisty ciąg w pamięci w postaci .

Następnie pokazuje zdjęcie urządzenia iOS z mutacjami.

A w official documentation mamy:

Struny są niezmienne (stała), więc nie można wskaźnik do łańcucha jako tablicy i manipulować znaków w ciąg. Jeśli spróbujesz zmodyfikować ciąg znaków, kompilatory przenośne Delphi mogą emitować komunikat: W1068 Zmodyfikowane ciągi w miejscu mogą nie być obsługiwane w przyszłości (Delphi).Można określić, czy komunikat x1068 jest emitowany jako ostrzeżenie lub błąd o wartości . Na stronie Wskazówki i ostrzeżenia ustaw ostrzeżenie "Modyfikuj łańcuchy w miejscu ...." na "true" lub "error".

Więc interpretuję to wszystko w ten sposób, że wersja XE4 kompilatora iOS ma wciąż zmienne łańcuchy. Programiści naprawdę nie chcą, abyś zmutował twoje struny i powiedzieli ci, że ciągi są niezmienne na kompilatorach mobilnych. Ale wydaje się, że wciąż można je zmienić. Domyśl!


Dostałeś jednak informację, że w przyszłym wydaniu ciąg może stać się niezmienny.

można przygotować się do tej przyszłej wersji teraz ustawiając

{$WARN IMMUTABLE_STRINGS WARN} 

który daje wyobrażenie o wpływie zmian. Jeśli chcesz brać się i przestać mutacji sznurki, można to zrobić:

{$WARN IMMUTABLE_STRINGS ERROR} 

Gdy to zrobisz musisz konwertować kod, który uzyskuje dostęp do poszczególnych elementów ciągów. Podejrzewam, że będziesz zaskoczony tym, jak mało jest takiego kodu. Właśnie skompilowałem 600 000 linii kodu i widziałem tylko 120 wystąpień ostrzeżenia. A większość z nich była w jednostkach zewnętrznych. Zauważyłem sporo poruszenia na temat tej zmiany, ale szczerze mówiąc nie wierzę, że bardzo wiele kodu zmutowuje łańcuchy. W przytłaczającej większości przypadków łańcuchy są tworzone przez konkatenację lub przez wywołania funkcji takich jak Format. Kod ten nie ma na to wpływu.

Nie sądzę, że są jakieś wielkie pułapki. Możesz użyć {$WARN IMMUTABLE_STRINGS ...}, aby kompilator przeprowadził Cię przez proces. Każdy kod, który mutuje ciągi znaków, powinien zostać przekonwertowany do użycia TStringBuilder.

chodzi o korzyściach płynących z niezmienności, odsyłam Cię do Why .NET String is immutable?

Jeśli używasz tradycyjnych kompilatory Windows lub OSX to nie widzę powód do zmiany. Kompilator iOS jest zupełnie nowy. Zmiana niezmiennych łańcuchów została uniesiona, ale może się to nigdy nie zdarzyć. Może się zdarzyć tylko na kompilatorach mobilnych, a nigdy na tradycyjnych kompilatorach. W tej chwili siedziałem napięty i czekałem, aby zobaczyć, jak to wszystko się dzieje.

+3

Tim Anderson jest również zdezorientowany tym, jak bardzo niezmienny jest nowy niezmienny ciąg mobilny: http://www.itwriting.com/blog/7347-changes-in-the-delphi-language-for-arm-and-mobile- support.html –

+3

Woah, trochę boję się wyciągać wnioski, ale to brzmi jak kolejny zły pomysł deweloperów Delphi. Przerwijmy kompilację, aby ciągi były mniej przydatne, świetny plan. – himself

+3

@himself Istnieją korzyści z niezmiennością. W każdym razie jest to bardzo niewielka zmiana. Pomijając biblioteki stron trzecich, którymi zajmą się inne osoby, mogę naprawić kod w ciągu godziny.Wolałbym, żeby usunięto część języka, nawet jeśli oznacza to jakiś ból po naszej stronie. –