今回のDelphi2009(Win32)は面白そうな機能追加が多くあり、購入を考えているので体験版をダウンロードして使ってみました。ちなみに現在持っているのはDelphi2005です。
起動時間について
Delphi2005は遅いと有名で、2006の時点で起動時間の問題は解消されています。2009の起動時間はそんなに長くなかった(おそらく2007と同じぐらい?もしくはもっと速い)です。私のマシンだとArchitectでおよそ20秒程度。
Unicodeについて
今まではString型がAnsiでしたが、2009ではUnicodeになっています。かなり詳しく書かれているページがあったのでリンクしておきます。
http://homepage1.nifty.com/ht_deko/tech014.html
コードページを指定した文字列型の定義ができるようになっています。
フォームのデザイナでも入力できていますね。
コードエディタではフォントの問題?のせいかハングルなどは表示できませんでした。
TMemoやら標準コンポーネントの挙動が気になっていたので試してみました。
procedure TForm1.Button1Click(Sender: TObject); begin Memo1.Lines.SaveToFile('test.txt'); end;
フォームにボタンとメモを置いただけのアプリケーションで、TStringsのSaveToFileを使ってみます。この場合、保存されるファイルの文字コードはShiftJISでした。ハングル文字は"?"となっています。
今回、SaveToFileメソッドは、引数としてエンコーディングを指定できるようになっていて、例えばUTF-8で保存するには次のようにします。
procedure TForm1.Button1Click(Sender: TObject); begin Memo1.Lines.SaveToFile('test.txt', TEncoding.UTF8); end;
TEncodingクラスのクラスプロパティやクラスメソッドがエンコーディングを返してくれるようです。ちなみにBOM付きのUTF-8でした。BOMなしにする方法を知りたい。
Anonymous Methods(匿名メソッド)について
匿名メソッドを使えるようになりました。
Tiburon - Anonymous Methods
クロージャも使えます。
program sample_anonymous_methods; {$APPTYPE CONSOLE} type TIntFunc = reference to function: Integer; function Counter(init: Integer = 0; step: Integer = 1): TIntFunc; var count: Integer; begin count := init; Counter := function: Integer begin Inc(count, step); Result := count; end; end; var c1, c2: TIntFunc; begin c1 := Counter(); // c1 count = 0, step = 1 のfunction c2 := Counter(2, 5); // c2 count = 2, step = 5 のfunction Writeln('c1:', c1); // c1 Inc(count, 1) => 1 Writeln('c1:', c1); // c1 Inc(count, 1) => 2 Writeln('c2:', c2); // c2 Inc(count, 5) => 7 Writeln('c1:', c1); // c1 Inc(count, 1) => 3 Writeln('c2:', c2); // c2 Inc(count, 5) => 12 Writeln('c1:', c1); // c1 Inc(count, 1) => 4 Readln; end.
出力結果。
c1:1 c1:2 c2:7 c1:3 c2:12 c1:4
reference toで宣言したtypeを使うときは、カッコの省略に気をつけたほうがいいかも。
Genericsについて
program sample_generics; {$APPTYPE CONSOLE} uses Generics.Collections; type THoge<T> = class private FValue: T; public constructor Create(Value: T); function GetValue: T; end; constructor THoge<T>.Create(Value: T); begin FValue := Value; end; function THoge<T>.GetValue: T; begin GetValue := FValue; end; var o1: THoge<String>; o2: THoge<Integer>; o3: TList<Integer>; i: Integer; o4: TObjectList<THoge<String>>; j: Integer; begin o1 := THoge<String>.Create('ほげ'); try Writeln('o1:', o1.GetValue); finally o1.Free; end; o2 := THoge<Integer>.Create(12345); try Writeln('o2:', o2.GetValue); finally o2.Free; end; o3 := TList<Integer>.Create; try o3.Add(22); o3.Add(5); o3.Add(17); o3.Sort; for i := 0 to o3.Count - 1 do begin Writeln('o3:', o3.Items[i]); end; finally o3.Free; end; o4 := TObjectList<THoge<String>>.Create; try o4.Add(THoge<String>.Create('ほげ')); o4.Add(THoge<String>.Create('ふが')); o4.Add(THoge<String>.Create('foo')); //o4.Sort; THogeなのでソートできず for j := 0 to o4.Count - 1 do begin Writeln('o4:', o4.Items[j].GetValue); end; finally o4.Free; end; Readln; end.
Generics.CollectionsユニットにTList
出力結果。
o1:ほげ o2:12345 o3:5 o3:17 o3:22 o4:ほげ o4:ふが o4:foo
こんなこともできるらしい。
Owl's perspective: ジェネリクスでイベントのマルチキャストを実現
実行ファイルについて
ビルドして生成された実行ファイルは、相変わらず単体で動作(.netやらランタイムライブラリなどいらず)します。
ファイルサイズはボタンとメモを置いただけのアプリケーションで512KBでした。
Generics.Collectionsを使ったフォームアプリは変わらず512KB。
コンソールアプリでSystemのみだと25KBぐらい。
Generics.Collectionsを使ったコンソールアプリで123KBぐらい。
おわりに
Win32ネイティブなアプリで、ここまでできるって結構すごい。おそらく買う。