列挙型
列挙型は、define-enum で定義される指定された要素の固定リストです。列挙型は、クラスのようなメソッドの追加ができません。要素名を設定することと、簡単な値(数値、char、bool、String)を設定することが可能です。列挙型を使うことで、定数に型を持たせることができますので、パラメータなどで使用可能な値の制限を簡単に実現できます。
null型
null は、拡張クラス型(#型名で表現されるnull値を許すクラス型)またはプロシージャ型の変数で利用できる「なにもない」状態を表します。null をプリミティブ型の変数 (数量など)、または通常の非nullクラス型の変数に代入することはできません。
拡張クラス型またはプロシージャ型の変数に null 値が設定されている場合は、変数に現在オブジェクトがないことを表しています。変数にオブジェクトを代入すると、この変数は null 値ではなくなります。null が許されているデータ型の変数に、null値を明示的に代入することもできます。
void型
値を返さないプロシージャまたはメソッドの戻り値のデータ型となります。クラスのメソッドなどの戻り値として頻繁に指定しますが、この型をプログラム処理で利用することはあまり無いと思われます。
any型
どのようなデータの処理をするかわからないような場合、すべての型に対応するのが、any 型です。any 型の変数には、プリミティブ型、クラス型、プロシージャ型などのすべてのデータ型の値を代入できます。null値を代入することもできます。any型を利用すると、Curlの実行環境への負荷が重くなります。最低限の使用にとどめましょう。
Typeクラス
以上でデータ型の説明は終わりです。次は、これらのデータ型をささえる仕組みについて見ていきます。
Curl言語が優れているのは、データ型をプログラムで容易に扱え、処理に一貫性がある点です。今まで説明してきたすべての型は、すべてTypeクラスのサブクラスの「インスタンス」になります。Typeクラスのサブクラスではないので注意してください。
Typeクラスの構成は、図1、表1のようになります。
サブクラス | 対応する型 | 具体的なインスタンス |
---|---|---|
NumericType | プリミティブ型 | int, uint, double, bool など |
ClassType | クラス型 | Object, String, Dateなど全ての define-class で定義したクラス |
ProcType | プロシージャ型 | 全ての define-procで定義したプロシージャ |
NullType | null型 | nullのみ |
EnumType | 列挙型 | 全ての define-enumで定義した列挙 |
AnyType | any型 | anyのみ |
VoidType | void型 | voidのみ |
具体的に説明しますと、int型はTypeクラスのサブクラスであるNumericTypeクラスのインスタンスになります。すべてのプリミティブ型はこのNumericTypeクラスのインスタンスとして定義されます。
同様に、define-class で定義されるすべてのクラス型はTypeクラスのサブクラスであるClassTypeクラスのインスタンスになります。
これらのTypeクラス、Typeクラスのサブクラスを使う事で、強力なリフレクションの機能を実現しています。「すべてのデータ型はTypeクラスの(サブクラスの)インスタンスになる」この意味が分かれば、応用範囲はとても広くなります。
type-ofマクロ
変数(インスタンス)からデータ型を得るために、type-of マクロが用意されています。マクロの中でも比較的わかりやすいもので、type-of の引数として変数を設定するだけで利用できます。
すべてのデータ型は、Typeクラスのインスタンスですので、各データ型を type-ofマクロの引数にした例を以下に示します。実行結果を見やすくするために、サンプルコードがやや読みにくくなっていますがご了承ください。
{curl 7.0 applet} {curl-file-attributes character-encoding = "shift-jis"} || 列挙型用定義 {define-enum Car sedan, rv, coupe } || Table作成 || {Table columns = 3, border-width=1px, border-color="gray", cell-border-width=1px, cell-border-style="sunken", cell-border-color="gray", || {row-prototype "void型", "void", {type-of void}}, || {row-prototype "any型", "any", {type-of any}}, || {row-prototype "null型", "null", {type-of null}}, || {row-prototype {cell-prototype "プリミティブ型", rowspan=6}, {cell-prototype "int"}, {cell-prototype {type-of int}} }, {row-prototype {skip 1}, "uint", {type-of uint}}, {row-prototype {skip 1}, "byte", {type-of byte}}, {row-prototype {skip 1}, "bool", {type-of bool}}, {row-prototype {skip 1}, "char", {type-of char}}, {row-prototype {skip 1}, "Angle", {type-of Angle}}, || {row-prototype {cell-prototype "クラス型", rowspan=4}, {cell-prototype "Object"}, {cell-prototype {type-of Object}} }, {row-prototype {skip 1}, "Type", {type-of Type}}, {row-prototype {skip 1}, "DateTime", {type-of DateTime}}, {row-prototype {skip 1}, "String", {type-of String}}, || {row-prototype "ProcType型", "proc-type", {type-of {proc-type {any}:int}} }, || {row-prototype "列挙型", "Car", {type-of Car}} }
実行結果です(図2)。
いくつか興味深い結果がでています。nullのタイプが NullType とならずに Null となっています。そして、String が StringType という独自のクラスタイプで定義されている点です。StringTypeは、リファレンスにはでてきません。想像ですが、Curl実行環境が文字列(StringInterface)について特別な処理をしているので、特別扱いしていると思われます。もちろん、StringType は ClassType を継承しています。