Pascal には 2 種類の型宣言があります。
- 型エイリアス: type NewName = OldType
- タイプの作成:タイプ NewType =タイプOldType
前者は、C のtypedefのように、便利な省略形を作成しているだけです。エイリアスは、互いに互換性があり、元の型と互換性があります。作成された型は意図的に互換性がなく、明示的でない限り混合できず、定義により安全ではありません。
var
nn: NewName; nt: NewType; ot: OldType;
...
nn := ot; // should work
nt := ot; // should break with type safety violation error.
nt := NewType(ot); // Disabling type safety. Should work even if
// it has no sense semantically and types really ARE incompatible.
私が理解しているように、これらはパスカルの基本です。
ここで、特定の型 1 つとそのエイリアス 2 つを見てみましょう。
- System.Types.TStringDynArray =文字列の配列。
- System.TArray<T> = Tの配列。
- 特に、 TArray<string> =文字列の配列; 定義により。
ここで、前者の型エイリアスを返す関数を取り、その結果を後者を期待する関数にフィードしましょう。
uses Classes, IOUtils;
TStringList.Create.AddStrings(
TDirectory.GetFiles('c:\', '*.dll') );
TStringList.Create.AddStrings(
TArray<string>( // this is required by compiler - but why ???
TDirectory.GetFiles('c:\', '*.dll') ) );
1 番目のスニペットは型違反のためコンパイルされません。2 番目のものは問題なくコンパイルおよび動作しますが、将来の型の変更に対して脆弱であり、冗長です。
QC は、コンパイラが正しく、RTL 設計が間違っていることを示します。 http://qc.embarcadero.com/wc/qcmain.aspx?d=106246
なぜコンパイラがここにあるのですか? これらのエイリアスが互換性がないのはなぜですか? RTL が設計されたまさにその方法でさえ、それらが互換性があると見なされたことを示唆しています!
PS。David は、TArray<T> を使用せずに、さらに単純な例を提案しました
type T1 = array of string; T2 = array of string;
procedure TForm1.FormCreate(Sender: TObject);
function Generator: T1;
begin Result := T1.Create('xxx', 'yyy', 'zzz'); end;
procedure Consumer (const data: T2);
begin
with TStringList.Create do
try
AddStrings(data);
Self.Caption := CommaText;
finally
Free;
end;
end;
begin
Consumer(Generator);
end;
説明なしで同じ落とし穴...
PPS。現在、多数のドキュメント参照があります。1 つのことを強調したいと思います。この制限は 1949 年のパスカル レポートから間接的に継承されている可能性がありますが、今日は 2012 年であり、Delphi は半世紀前の学校の研究室とは大きく異なって使用されています。この制限を守ることの悪い影響をいくつか挙げましたが、良い影響は見当たりませんでした。
皮肉なことに、Pascal の規則を破ることなくこの制限を解除することができます。Pascal には、Open Array や Dynamic Array のような非厳密な獣はありません。したがって、これらの元の固定配列は好きなように制限できますが、オープン配列と動的配列は Pascal 市民ではなく、そのコードブックによって制限される義務はありません!
QC またはここでも Emba に連絡してください。ただし、意見を表明せずに通り過ぎるだけでは、何も変わりません。