型システム リファレンス

NagiScript の型システム全体を解説します。

現行仕様(v0.2.0)

以下は現行コンパイラー 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
現行仕様(v0.2.0)

str と書くと unknown type `str` エラーになるため、string を使ってください。単型 void は存在しません。戻り値がない関数は -> を書かず、戻り値を返す場合は fn name(...) -> 型 の -> 構文を使い、ブロック末尾の暗黙 return ではなく必ず return を明示してください。

main.ngs
fn greet(name: string) -> string {
    return name
}

fn do_nothing() { }  // 戻り値なし。void は不要

fn main() {
    println(greet("Nagi"))
}

複合型

配列型 ([T; N])

main.ngs
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
現行仕様(change.md, 2026-08)

固定長配列 [T; N] に .len() メソッド(および従来からの関数形式 len(a))が使えます。長さはコンパイル時に判明する定数として扱われるため実行時オーバーヘッドはありません。大きさは型に含まれるため、string 同様に value 型として扱えます。配列の長さの異なる型への代入は型エラーになります。

構造体 (Struct)

main.ngs
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)
現行仕様(v0.2.0)

構造体は値渡しです。フィールドアクセスは p.x。メソッドは impl ブロックで定義し、self に型注釈が必要です(例: fn show(self: Point) -> string)。

列挙型 (Enum)

main.ngs
enum Status { Ok NotFound }

fn show(s: Status) {
    val st = match s {
        Ok => "200",
        _ => "404",
    }
    println(st)
}

fn main() {
    show(Status.Ok)
}
現行仕様(v0.2.0)

enum のバリアント値は Status.Ok のように括弧なしで生成します(データを持つバリアントのみ括弧が必要、例: Some(42))。match のパターンは裸のバリアント名(Ok 等)と _ ワイルドカードです。

タプル

ロードマップ(未実装)

(i32, string) のようなタプルや val (a, b) = ... のデストラクチャリングは未実装 / 未検証です。複数の値をまとめる場合は構造体を使ってください。

main.ngs
struct Pair {
    first: i32
    second: string
}

val p = Pair { first: 42, second: "hello" }
println(p.second)

ジェネリクス型

ロードマップ(未実装)

Vec2<T> のような型パラメータ付き構造体や Gen<T> は未実装 / 未検証です。型パラメータが使えるのは List<i32> など限定的です。通常は型パラメータなしの構造体を使い、具象型で定義してください。

main.ngs
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 で分岐してください。

main.ngs
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>

現行仕様(v0.2.0)

List<T> は List.new() / push / len / get / set の API が存在しますが、LLVM コード生成で zext i64 to i64 エラーが発生してリンクに失敗する既知バグがあります。また Rc<T> は使用可能な型の一つですが、Rc.new(値) / .get() の .get() 戻り値は要検証です。当面は構造体 + 値渡しを推奨します。

main.ngs
struct Item {
    value: i32
}

struct Box {
    item: Item
}

fn main() {
    val b = Box { item: Item { value: 42 } }
    println(b.item.value)
}

型変換

現行仕様(v0.2.0)

型変換は as 演算子を使います。暗黙の数値変換(i64 → i32 の自動縮小など)への依存は避けてください。

明示的なキャスト

main.ngs
val x: i32 = 42
val y: f64 = x as f64  // 明示的な型変換
val n: i64 = x as i64

ポインタ型

現行仕様(v0.2.0)

ポインタ型は *T 形式(例: *i32)です。*const T / *mut T の区別はありません。アドレスは &x as *i32、参照解除は unsafe { *ptr } で行います。ptr-> / ptr.offset(n) は未検証のため、*ptr と整数演算で代替してください。

基本的なポインタ

main.ngs
fn read(ptr: *i32) -> i32 {
    unsafe { return *ptr }
}

fn main() {
    var x = 42
    val p = &x as *i32
    println(read(p))  // 42
}

配列ポインタ

main.ngs
var arr: [i32; 3] = [1, 2, 3]
val ptr: *i32 = &arr[0]
unsafe {
    println(*ptr)
}

関数型

ロードマップ(未実装)

関数型フィールド(handler: fn(Request) Response 等)や高階関数は現行では不安定なため非推奨です。関数ポインタの代わりに、id(i32)フィールドと if 分岐で処理を切り替えてください。

main.ngs
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 キーワードは未実装のため、型エイリアスは定義できません。


型安全性

コンパイル時チェック

main.ngs
val x: i32 = 42
val y: string = "hello"

// 型エラー: i32 と string は加算できない
// val z = x + y  // コンパイルエラー

実行時チェック

現行仕様(v0.2.0)

List<T> は zext i64 to i64 のリンク失敗という既知バグがあるため、現在は構造体 + 値渡しの利用を推奨します。またポインタの参照解除は必ず unsafe ブロック内で行ってください。