16

iOS プラットフォーム用の Delphi XE4 では、新しい文字列型が導入されました。不変のゼロ ベースの文字列です。これまでのところ、Delphi にはコピー オン ライトの可変文字列がありました。問題は、それが私の将来のプログラミングにとって何を意味するのかということです。ある文字列型が他の文字列型よりも優れている点はありますか? 新しい文字列タイプに切り替えるときに注意する必要がある落とし穴は何ですか (明らかな 0 対 1 ベース以外)?

4

1 に答える 1

17

Marco Cantù のホワイトペーパーによると、XE4 iOS ターゲットのstringデータ型は実際には不変ではありませんが、彼は矛盾しているようです。

彼は言い​​ます:

新しい Delphi LLVM ベースのコンパイラには、Unicode 文字列(UTF16)を表す 1 つの文字列型があり、Delphi XE3 の現在の文字列型にマップされます(Windows コンパイラの UnicodeString 型のエイリアス)。ただし、この新しい文字列型では、別のメモリ管理モデルが使用されます。文字列型は引き続き参照カウントされますが、不変です。つまり、一度構築された文字列の内容を変更することはできません。

しかし、彼は続けてこう言います。

つまり、文字列はUnicode ベースになり、間もなく不変になり、参照カウントされます。

また:

ただし、変化が始まるのは、既存の文字列を新しい値に置き換えるのではなく (この場合、まったく新しい文字列が得られます)、その要素の 1 つを変更するときです。コード (およびトピックを紹介した前のセクションでも):

Str1 [3] := 'x';

すべての Delphi コンパイラは、コピー オン ライト セマンティクスを使用します。変更する文字列に複数の参照がある場合、最初にコピーされ(必要に応じて関連するさまざまな文字列の参照カウントを調整します)、後で変更されます。

新しいコンパイラは、従来のコンパイラと非常によく似た処理を行います。文字列への単一の参照がない限り、コピーオンライトメカニズムを実装します。その場合、文字列はその場で変更されます。例として、実際の文字列のメモリ内の場所を出力する次のコードを考えてみましょう。

そして、文字列が変化する iOS デバイスの写真を見せます。

そして、公式ドキュメントには次のものがあります。

文字列は不変 (定数) であるため、文字列に配列としてインデックスを付けたり、文字列内の文字を操作したりすることはできません。文字列を変更しようとすると、Delphi モバイル コンパイラがメッセージ W1068 Modifying strings in place is not supported in future (Delphi) を出力する場合があります。メッセージ x1068 を警告またはエラーとして出力するかどうかを指定できます。Hints and Warnings ページで、警告「Modifying strings in-place....」を「true」または「error」に設定します。

したがって、私はこれらすべてを、iOS コンパイラの XE4 リリースにはまだ変更可能な文字列があることを意味していると解釈しています。開発者は、これ以上文字列を変更することを望んでおらず、モバイル コンパイラでは文字列が不変であると言っています。しかし、それらはまだ可変であるように見えます。図に行く!


ただし、将来のリリースでは文字列が不変になる可能性があることに注意してください。

設定することで、その将来のリリースに今すぐ備えることができます

{$WARN IMMUTABLE_STRINGS WARN}

これにより、変更の影響がわかります。バックルを締めて文字列の変異を止めたい場合は、次のようにします。

{$WARN IMMUTABLE_STRINGS ERROR}

これを行ったら、個々の文字列要素にアクセスするコードを変換する必要があります。そのようなコードがいかに少ないかに驚かれると思います。600,000 行のコードをコンパイルしたところ、警告のインスタンスが 120 回しか表示されませんでした。そして、それらのほとんどはサードパーティのユニットにありました。私はこの変更についてかなりの騒ぎを見てきましたが、正直なところ、多くのコードが文字列を変更しているとは思いません。圧倒的多数の場合、文字列は連結または のような関数の呼び出しによって構築されますFormat。そのコードはこれによる影響を受けません。

大きな落とし穴はないと思います。を使用{$WARN IMMUTABLE_STRINGS ...}して、コンパイラにプロセスを案内させることができます。文字列を変更するコードは、 use に変換する必要がありますTStringBuilder

不変性の利点については、Why .NET String is immutable?を参照してください。

従来の Windows または OSX コンパイラを使用している場合、変更する説得力のある理由はないと思います。iOS コンパイラはまったく新しいものです。不変文字列への変更は保留されていますが、実現しない可能性があります。これはモバイル コンパイラでのみ発生する可能性があり、従来のコンパイラでは発生しない可能性があります。今のところ、私はじっと座って、すべてがどのように展開するかを待ちます.

于 2013-04-25T10:48:00.883 に答える