型システム リファレンス
NagiScript の型システム全体を解説します。
以下は現行コンパイラー v0.2.0
で実際に使用できる仕様です。str /
void / タプル /
ジェネリクス構造体など、ドキュメントに散見される「将来仕様」は現行では動作しないため、各項目の注記を必ず確認してください。
基本型
整数型
| 型 | ビット幅 | 範囲 | デフォルト |
|---|---|---|---|
i8 |
8 | -128 〜 127 | |
i16 |
16 | -32,768 〜 32,767 | |
i32 |
32 | 約 ±21 億 | ✓ |
i64 |
64 | 約 ±922京 | |
u8 |
8 | 0 〜 255 | |
u16 |
16 | 0 〜 65,535 | |
u32 |
32 | 0 〜 約42億 | |
u64 |
64 | 0 〜 約1844京 | |
isize |
ワード幅 | ポインタサイズの符号あり整数 | |
usize |
ワード幅 | ポインタサイズの符号なし整数 |
浮動小数点型
| 型 | ビット幅 | 精度 |
|---|---|---|
f32 |
32 | 約7桁 |
f64 |
64 | 約15桁 |
その他の基本型
| 型 | 説明 |
|---|---|
bool |
真偽値 (true / false) |
string |
文字列(不変)。型名は str ではなく
string
|
str と書くと
unknown type `str` エラーになるため、string
を使ってください。単型
void は存在しません。戻り値がない関数は
-> を書かず、戻り値を返す場合は
fn name(...) -> 型 の
-> 構文を使い、ブロック末尾の暗黙 return
ではなく必ず return を明示してください。
fn greet(name: string) -> string {
return name
}
fn do_nothing() { } // 戻り値なし。void は不要
fn main() {
println(greet("Nagi"))
}
複合型
配列型 ([T; N])
var a: [i32; 3] = [10, 20, 30]
println(a[0]) // 10(インデックスアクセス)
println(a.len()) // 3(メソッド形式、change.md 2026-08 で追加)
println(len(a)) // 3(関数形式)
val b = [1, 2]
a[0] = b[0] + b[1] // 要素の代入
println(a[0]) // 3
固定長配列 [T; N] に
.len() メソッド(および従来からの関数形式
len(a))が使えます。長さはコンパイル時に判明する定数として扱われるため実行時オーバーヘッドはありません。大きさは型に含まれるため、string
同様に value 型として扱えます。配列の長さの異なる型への代入は型エラーになります。
構造体 (Struct)
struct Point {
x: f32
y: f32
}
struct Person {
name: string
age: i32
email: string
}
val p = Point { x: 3.0, y: 4.0 }
println(p.x)
構造体は値渡しです。フィールドアクセスは
p.x。メソッドは
impl ブロックで定義し、self
に型注釈が必要です(例:
fn show(self: Point) -> string)。
列挙型 (Enum)
enum Status { Ok NotFound }
fn show(s: Status) {
val st = match s {
Ok => "200",
_ => "404",
}
println(st)
}
fn main() {
show(Status.Ok)
}
enum のバリアント値は
Status.Ok のように括弧なしで生成します(データを持つバリアントのみ括弧が必要、例: Some(42))。match
のパターンは裸のバリアント名(Ok 等)と
_ ワイルドカードです。
タプル
(i32, string) のようなタプルや
val (a, b) = ... のデストラクチャリングは未実装
/
未検証です。複数の値をまとめる場合は構造体を使ってください。
struct Pair {
first: i32
second: string
}
val p = Pair { first: 42, second: "hello" }
println(p.second)
ジェネリクス型
Vec2<T> のような型パラメータ付き構造体や
Gen<T> は未実装 /
未検証です。型パラメータが使えるのは
List<i32>
など限定的です。通常は型パラメータなしの構造体を使い、具象型で定義してください。
struct Vec2 {
x: f32
y: f32
}
val v = Vec2 { x: 1.0, y: 2.0 }
println(v.y)
複数の型パラメータ
Pair<A, B>
のような複数の型パラメータは未実装です。フィールドの型は具象型で指定してください。
標準ジェネリクス型
Option<T> / Result<T, E>
組み込みの Option<T> /
Result<T, E> は存在しません。?
演算子も未実装です。成否を表す型は
enum で自作し、match
で分岐してください。
enum Status { Ok NotFound }
fn find(id: i32) -> Status {
if id == 1 {
return Status.Ok
}
return Status.NotFound
}
fn main() {
val st = find(2)
val s = match st {
Ok => "found",
_ => "not found",
}
println(s)
}
List<T> / Rc<T>
List<T> は List.new() /
push / len / get /
set の API が存在しますが、LLVM コード生成で
zext i64 to i64
エラーが発生してリンクに失敗する既知バグがあります。また
Rc<T> は使用可能な型の一つですが、Rc.new(値)
/ .get() の
.get() 戻り値は要検証です。当面は構造体 +
値渡しを推奨します。
struct Item {
value: i32
}
struct Box {
item: Item
}
fn main() {
val b = Box { item: Item { value: 42 } }
println(b.item.value)
}
型変換
型変換は
as 演算子を使います。暗黙の数値変換(i64
→
i32 の自動縮小など)への依存は避けてください。
明示的なキャスト
val x: i32 = 42
val y: f64 = x as f64 // 明示的な型変換
val n: i64 = x as i64
ポインタ型
ポインタ型は *T 形式(例:
*i32)です。*const T /
*mut T の区別はありません。アドレスは
&x as *i32、参照解除は
unsafe { *ptr } で行います。ptr->
/ ptr.offset(n) は未検証のため、*ptr
と整数演算で代替してください。
基本的なポインタ
fn read(ptr: *i32) -> i32 {
unsafe { return *ptr }
}
fn main() {
var x = 42
val p = &x as *i32
println(read(p)) // 42
}
配列ポインタ
var arr: [i32; 3] = [1, 2, 3]
val ptr: *i32 = &arr[0]
unsafe {
println(*ptr)
}
関数型
関数型フィールド(handler: fn(Request) Response
等)や高階関数は現行では不安定なため非推奨です。関数ポインタの代わりに、id(i32)フィールドと
if 分岐で処理を切り替えてください。
struct Handler {
id: i32
}
fn run(h: Handler) {
if h.id == 0 {
println("handler A")
} else {
println("handler B")
}
}
fn main() {
run(Handler { id: 1 })
}
型エイリアス
type
キーワードは未実装のため、型エイリアスは定義できません。
型安全性
コンパイル時チェック
val x: i32 = 42
val y: string = "hello"
// 型エラー: i32 と string は加算できない
// val z = x + y // コンパイルエラー
実行時チェック
List<T> は
zext i64 to i64
のリンク失敗という既知バグがあるため、現在は構造体 +
値渡しの利用を推奨します。またポインタの参照解除は必ず
unsafe ブロック内で行ってください。
