Delphi XE4 неизменяемые строки - программирование
Подтвердить что ты не робот

Delphi XE4 неизменяемые строки

В Delphi XE4 для платформы iOS был введен новый тип строки: неизменяемые нулевые строки. До сих пор у Delphi была копия на запись изменяемых строк. Итак, вопрос в том, что это значит для моего будущего программирования? Существуют ли какие-либо преимущества одного типа струны над другим? Каковы подводные камни, которые мне нужно позаботиться при переключении на новый тип строки (кроме очевидной базы 0 против 1)?

4b9b3361

Ответ 1

Согласно технический документ Marco Cantpaper, тип данных string в целевой точке iOS XE4 на самом деле не является неизменным, хотя он, похоже, противоречат самому себе.

Он говорит:

В новом компиляторе Delphi LLVM существует один строковый тип, представляющий строки Unicode (UTF16) и сопоставляемый с текущим строковым типом в Delphi XE3 (псевдоним для типа UnicodeString в компиляторе Windows). Однако этот новый тип строки использует другую модель управления памятью. Строковый тип по-прежнему подсчитывается по ссылке, но он неизменен, что означает, что вы не можете изменять содержимое строки после ее создания.

Но он затем продолжает:

Другими словами, строки теперь основаны на Unicode, скоро станут неизменными и подсчитаны по ссылке.

А также:

Однако, когда все начинает меняться, это когда вы изменяете существующее string, а не заменяя его новым значением (в этом случае вы получаете новая строка), но при изменении одного из его элементов, как показано в эта строка кода (а также в предыдущем разделе, где я ввел тему):

Str1 [3] := 'x';

Все компиляторы Delphi используют семантику copy-on-write: если строка, которую вы modify имеет более одной ссылки, он сначала копируется (корректировка подсчет ссылок на различные строки, если это необходимо) и позже измененный.

Новый компилятор делает что-то очень похожее на классическое. Это реализует механизм копирования на запись, если нет единственного ссылка на строку, и в этом случае строка изменяется место. В качестве примера рассмотрим следующий код, который выводит в ячейке памяти фактической строки.

Затем он показывает изображение устройства iOS с мутировавшимися строками.

И в официальной документации мы имеем:

Строки неизменяемы (постоянны), поэтому вы не можете индексировать строку массив и манипулировать символами в строке. Если вы попытаетесь изменить строку, мобильные компиляторы Delphi могут выдать сообщение W1068 Изменение строк на месте может не поддерживаться в будущем (Delphi). Вы можете указать, выбрано ли сообщение x1068 как предупреждения или ошибки. На странице "Советы и предупреждения" установите предупреждение "Изменение строк на месте..." на "true" или "error".

Итак, я интерпретирую все это как значение, что релиз XE4 компилятора iOS по-прежнему имеет изменяемые строки. Разработчики действительно не хотят, чтобы вы больше мутировали свои строки и говорите вам, что строки неотменяемы для мобильных компиляторов. Но они все еще кажутся изменчивыми. Пойдите фигурой!


Однако вам сообщили, что в будущей версии строка может стать неизменной.

Теперь вы можете подготовиться к этой будущей версии, установив

{$WARN IMMUTABLE_STRINGS WARN}

который даст вам представление о влиянии изменения. Если вы хотите застегнуть и остановить мутирующие строки, вы можете сделать это:

{$WARN IMMUTABLE_STRINGS ERROR}

После этого вам нужно будет преобразовать код, который обращается к отдельным строковым элементам. Я подозреваю, что вы будете удивлены, как мало такого кода есть. Я только что составил 600 000 строк кода и увидел только 120 экземпляров предупреждения. И большинство из них были в сторонних подразделениях. Я видел, как это изменение изменилось, но я, честно говоря, не верю, что очень много кода мутирует строки. В подавляющем большинстве случаев строки создаются путем конкатенации или вызовами функций типа Format. Этот код не влияет на это.

Я не думаю, что есть какие-то большие подводные камни. Вы можете использовать {$WARN IMMUTABLE_STRINGS ...}, чтобы компилятор проведет вас через этот процесс. Любой код, который мутирует строки, должен быть преобразован для использования TStringBuilder.

Что касается преимуществ неизменности, я отсылаю вас к Почему .NET String неизменна?

Если вы используете традиционные компиляторы Windows или OSX, то я не вижу веских причин для изменения. Компилятор iOS совершенно новый. Изменения в неизменяемые строки были перемещены, но этого никогда не произойдет. Это может произойти только на мобильных компиляторах и никогда не на традиционных компиляторах. Прямо сейчас, я сидел сидеть и ждать, чтобы посмотреть, как все это происходит.