基本のデータ型


プリミティブ型

Nemerle のプリミティブ型は以下の通りです。

型名 実際の型 概要 数値リテラルのサフィックス
bool System.Boolean ブール代数 (true|false)
sbyte System.SByte 8 ビット符号付き整数型 sb
byte System.Byte 8 ビット符号なし整数型 b または ub (16 進数表記の時は u の省略不可)
short System.Int16 16 ビット符号付き整数型 s
ushort System.UInt16 16 ビット符号なし整数型 us
int System.Int32 32 ビット符号付き整数型 なし
uint System.UInt32 32 ビット符号なし整数型 u
long System.Int64 64 ビット符号付き整数型 L
ulong System.UInt64 64 ビット符号なし整数型 uL
float System.Single 単精度浮動小数点数 (32 ビット IEEE 浮動小数点数) f
double System.Double 倍精度浮動小数点数 (64 ビット IEEE 浮動小数点数) d (小数点を含むか指数表記の場合は省略可)
decimal System.Decimal 10 進数 m
char System.Char Unicode 文字
string System.String 文字列
object System.Object オブジェクト

サフィックスは数値の直後に付けて数値の型を明示するための仕組みです。大文字でも小文字でも構いません。

整数リテラルは 10 進数表記のほか 16 進数表記と 2 進数表記が利用できます。また,小数リテラルは指数表記が利用できます。文字コードを 16 進数表記する場合は \u に 4 桁の 16 進数コードポイントを続けます。

def hex = 0xBEEF;  // 48879 と同じ
def bin = 0b10101;  // 21 と同じ
def exp = 1.23e-2;  // 0.0123 と同じ
def code = '\u3042';  // 'あ' と同じ

void

何もないことを表す特別な型に void があります。 void 型のリテラルは () です。

void に対して変数束縛は可能ですが,値が存在しないため, void 型の変数あるいはリテラルに対して操作を行う事はできません。

def x = ();
// System.Console.WriteLine(x);  // コンパイルエラー

タプル

タプルは複数の値を 1 つにまとめた値です。リテラル表現は,値をカンマ区切りにし, () 囲みます。以下にいくつか例を挙げます。

def tuple1 = (1, 2);  // int 2 つからなるタプル
def tuple2 = ('A', 'B', 'C');  // char 3 つからなるタプル
def tuple3 = (42, "foo");  // int と string からなるタプル
def tuple4 = (("key", "value"), 3);  // string 2 つからなるタプルと int からなるタプル

タプルの型を表記する場合は,要素の型を * でつなぎます。必要に応じて () でまとめます。上の例で型を明示すると以下のようになります。

def tuple1 : int * int = (1, 2);
def tuple2 : char * char * char = ('A', 'B', 'C');
def tuple3 : int * string = (42, "foo");
def tuple4 : (string * string) * int = (("key", "value"), 3);

タプルに変数を束縛する場合,タプル全体を束縛させることもできますし,一部を束縛させることもできます。一部と全体を受け取りたい場合は as を使います。これはパターンマッチと同じ要領です。

def (x, y) = tuple1;  // x = 1, y = 2
def (_, b, _) = tuple2;  // b = 'B'
def (answer, _) as t = tuple3;  // answer = 42, t = (42, "foo")
def ((key, _) as pair, count) = tuple4;  // key = "key", pair = ("key, "value"), count = 3

関数

ここでは関数の型についてのみ説明します。関数の定義の仕方については前章「関数」および「ラムダ式」をご覧ください。

T1 型のパラメーターを受け取って T2 型のパラメーターを返す関数の型は T1 -> T2 のように表現します。パラメーターがない場合は void を受け取ると考え,複数のパラメーターを受け取る場合はタプルを受け取るものと考えます。

// int -> int
Negate(x : int) : int
{
  -x;
}
// void -> void
def printHello()
{
  System.Console.WriteLine("Hello");
}
def multiply : int * int -> int = _ * _;

リスト

リストは複数の同じ型の要素からなる要素の集まりです。要素がないリストを空リストと呼びます。リストは先頭の要素と,それに続くリストという構造を持ち,末尾は空リストです。先頭から順次アクセスする操作に向いています。

リストのリテラル表現は,カンマ区切りの値を [] で囲みます。空リストは単に [] と書きます。また,要素の型が T であるリストの型は list[T] と表します。

def intList = [1, 2, 3];
def emptyList : list[string] = [];

範囲を指定してリストを作成する場合は, $[ lower .. upper ] という表記をします。

def smallLetters = $['a' .. 'z'];  // ['a', 'b', 'c', ..., 'y', 'z']

先頭要素とリストの連結は :: です。タプルの時と同様に,パターンマッチの表現で変数束縛できます。

def moreIntList = 0 :: intList;  // [0, 1, 2, 3]
def (head :: tail) = intList;  // head = 1, tail = [2, 3]

リストとリストの連結は + を用います。

def capitalLetters = $['A' .. 'Z'];
def alphabets = smallLetters + capitalLetters;

配列

一次元配列のリテラル表現は,値をカンマ区切りにし, array [] 囲みます。また,要素の型が T である一次元配列の型は array[T] と表します。

def intArray : array[int] = array [1, 2, 3];

多次元配列は, array.[n] のように次元数を array の後ろに .[] で示します。例えば 2 次元配列であれば次のようになります。

def matrix : array.[2][int] = array.[2] [[1, 2], [3, 4]];

なお,多次元配列と似たものにジャグ配列があります。ジャグ配列は,単に配列の要素が配列であるというだけの配列なので,多次元配列のような特別な記法はありません。

def jagged : array[array[int]] = array [array [1, 2], array [3, 4, 5]];

サイズだけを指定してデフォルト値 (0null) で埋められた配列を作成したい場合は,次のよう括弧内にサイズを指定します。

def zeroArray : array.[2][int] = array(2, 3);  // 2 x 3

この例では配列の型を明示していますが,省略した場合は,型推論により要素の型が決定されます

オプション

オプション型は変数の値が実際に存在する場合,存在しない場合の両方が考えられるときに使用します。値が存在するときは Some(value),存在しないときは None() を使います。

値が存在する場合の値の型を T とするとオプション型は option[T] と表します。

def parse(s)
{
   mutable value : int;
   def success = System.Int32.TryParse(s, out value);
   if (success) Some(value) else None();
}
def x : option[int] = parse("123");  // Some(123)
def y = parse("foo");  // None()

オプション型の値を利用する場合は,多くの場合にパターンマッチを利用します。

match (option)
{
   | Some(value) => System.Console.WriteLine("Value found ({0})", value);
   | None() => System.Console.WriteLine("Value not found.");
}