recordを自動で初期化したい

リンク元より。
http://delfusa.blog65.fc2.com/blog-entry-107.html

この分野に関しては、日本だと ytqwerty が一番詳しいと思う

わははは。そりゃ嘘です。塚越一雄様を筆頭に、いくらでもいるでしょうに。

邪道Delphianの自覚はありますので、正統派なとこはあまり近づかないようにしている(興味の方向がまるで違うため私的にも読んでて面白くないし)のですが、今回ばかりはコメント欄に自分の名前があるのを発見しまして、折角のご指名ですのでなんか考えようとしたのです、が、うん、見事に脳内ダラダラ。まとまりなし。意味不明でいい感じだ。
例によってスルー推奨。

まあ、recordを自動で初期化したいがために動的配列を使用して長さ1で使うなんてのは書かれてる通り馬鹿らしいのですが、需要がないこともないのも確かです。
まず、言及先の言及先の動的配列案が馬鹿らしいのは何故かと考えるに……。(←順序が逆)

  • 全メソッドの先頭で分岐が入る。昨今のCPUではキャッシュというものがあるので分岐は少なければ少ないほどよいともっぱらの噂です。
  • 必要も無いのにメモリマネージャを使う。動的な割り当てを避けたいからrecordじゃないのですか。そんならclassのほうがマシ。
  • なにより書くのがめんどくさい。

Create/FreeやらInit/Doneやらを書きたくない場合は、interfaceにしてしまうのが手っ取り早いのですが、あくまでメモリマネージャ無しで考えてみましょうか。

仮に……フィールドを自動で初期化される型にして、キャストして使う……と、自動で初期化される型は自動で解放もされてしまうので……落ちる。没。
自動で初期化されて自動では解放されないデータを考える……interface, String, Variant, 動的配列……この辺は全部だめ。ん?Text型やfile型なら自動で閉じられたりはしませんよね。ああダメだ。Text型やfile型は初期化もされません。あ、ShortStringの長さを格納してるとこって0にならないかな……ダメです。なりませんでした。
初期化されて解放されないのはobject型のVMTぐらいか。しかし、これをこのままフィールドに使うとしても、0じゃなくてメモリアドレスになるから、いまいち使い勝手が……絶対4の倍数なので下位2ビットなら使えますが。全ビット使おうと思えばやっぱ全メソッドにif文。

全メソッドにif文が馬鹿らしいというのが焦点なら、全メソッド一気に置き換えればいいんだよな。

メソッドは全部virtualにする。initializationかどっかでVMTを待避する。で、もともとVMTがあったところにサンクを作る。サンクは、フィールドを0で初期化して、VMTを待避先に書き換えて、本来のメソッドにjmpする。

こんな方針で、initializationにAutoInit(TypeInfo(T));入れとくだけでそのobject型は最初にメソッドを呼ぶときにフィールドが全部0初期化される、なんてのはできるかもしれない。

でも実際に使うなら……interfaceも、先のobject型にしてメソッド全部virtualも、実行時ディスパッチが無駄に入るのが。動的配列案は、そこだけは優れています。

やっぱ、あきらめてCreate/Free書くかな。

もしFreeだけ書きたくない、Createは書いてもよいというのであれば、ほかに手はあって、_Releaseだけ埋めたIUnknownの嘘VMT作って、適当なinterface型でフィールドに持たせておけば、呼ばれますしね。カスタムバリアントでもいいし、メソッドがinterfaceを返してわざと変数では受けない小技でもいいし。極端な話、どっかのリストに入れといて、Application.OnIdleで一括解放してもいいですし。

実は、Application.OnIdleで一括解放は、Thebeで使ってます。や、もちろん、VCLは使って無いので、正確にはメッセージキューが空になったとき、ですけど。この方法のメリットは、暗黙の例外ハンドラが作られないため、コードサイズが小さくなることです。デメリットは解放タイミングが予想できないこと。

……うーん、実際のとこ、TStringListなんて使わないなあ……function LoadTextFile(const Filename: string): TStringDynArray;の方がなにかと便利と思います。
TStringListを使うというのは、もちろんTStringsを受けるところに渡したいからでしょうけれど、コンテナが多態するよりは、コンテナを処理するルーチンを汎用的に作るのが世の中の流れみたいですしね。templateにするなりgenericにするなり多相型にするなり、PTypeInfoも一緒に受け取ってSystemユニットの関数で処理するなりすれば、何にでも使えるようになりますから。