Menu

Zero のプリミティブ型|整数・浮動小数点・Bool・String・Void

Zero が標準で提供するビルトイン型。あらゆる幅の符号付き・符号なし整数、浮動小数点、ブーリアン、文字、文字列、そして空の型 Void を解説します。

ビルトイン型

Zero は、小さく規則的なプリミティブ型のセットを提供します。エキゾチックなものも意外なものもなく、すべてのシステム言語が必要とするものを、一貫した名前で揃えているだけです。

ファミリー備考
符号付き整数i8i16i32i642 の補数表現。
符号なし整数u8u16u32u640 と正のみ。
ポインタサイズusizeisizeプラットフォームのポインタ幅に一致。
浮動小数点f32f64IEEE-754。
ブーリアンbooltrue または false
文字char単一の Unicode スカラー。
文字列StringUTF-8 文字列。
Void「有用な値はない」。

これが日常的に触れるプリミティブの全リストです。複合型——shapeenumchoice——はこれらから作られます。

整数

整数型は統一的な命名パターンに従います。符号付きは i、符号なしは u、続いてビット幅です。つまり i32 は 32 ビット符号付き整数、u8 は符号なしバイト、i64 は 64 ビット符号付き整数。

let small_signed: i8   = -120
let byte:         u8   = 250
let id:           i32  = 1
let big:          i64  = 9_000_000_000
let index:        usize = 0

サフィックスのないリテラルのデフォルトは、周囲のコンテキストが別のものを強制しない限り i32 です。

let answer = 42       // i32

特定の幅が必要な場合は、リテラルにサフィックスを付けるか、バインディングに注釈します。

let byte = 250_u8     // 型付きリテラル
let byte: u8 = 250    // 型付きバインディング

どちらの形も同じ値を生成します。リテラルサフィックス形式は、リテラルを直接関数に渡すときや構造体を組み立てるときに便利です。

let pair: BytePair = Pair { left: 1_u8, right: 2_u8 }

どの幅を選ぶか

簡単な目安です。

  • ほとんどの符号付き演算には i32 数えるものほぼ何にでも十分広く、どのプラットフォームでも高速。
  • バイトレベルの作業には u8 ファイルのバイト、バッファのバイト、ネットワーク越しのバイト。
  • 範囲が重要な非負カウントには u32 / u64 2GB を超えるファイルオフセット、大きなカウント。
  • サイズとインデックスには usize ポインタサイズ——プラットフォームがメモリアドレッシングに使うものに一致。
  • エポックからの時間などには i64 数百年分のナノ秒に十分な大きさ。

収まる最も小さな型を選ぶのは良い習慣ですが、小さすぎる型を選んでオーバーフローする方が、1 ビット広めの型を選ぶよりずっと大きな問題です。

ブーリアン

let ok = true
let done: bool = false

bool はちょうど 2 つの値、truefalse を持ちます。これらはどこかからインポートする定数ではなく、リテラルです。ifwhile の条件は bool です——整数や文字列に対する暗黙の真偽値解釈はありません。

if ok {
    check world.out.write("yes\n")
} else {
    check world.out.write("no\n")
}

条件分岐の詳細は If/Else で扱います。

浮動小数点

f32f64 はそれぞれ 32 ビット・64 ビットの IEEE-754 浮動小数点数です。小数の値が必要なとき——測定、比率、幾何——に使います。通貨に対する厳密な算術には、浮動小数点よりも最小単位(セント、satoshi)の整数を使うのが望ましいです。

let ratio: f32 = 0.5
let pi:    f64 = 3.141592653589793

サフィックスのない浮動小数点リテラルのデフォルトは f64 です。

文字と文字列

char は単一の Unicode スカラー値を保持します。

let initial: char = 'Z'

String は文字のシーケンスで、標準ライブラリでは通常 UTF-8 でエンコードされます。文字列リテラルはダブルクォートを使います。

let message: String = "hello from zero\n"

期待されるエスケープシーケンスは動きます——改行は \n、タブは \t、リテラルなバックスラッシュは \\、リテラルなダブルクォートは \"

let multi_line = "line one\nline two\n"

標準ライブラリは、低水準作業のための文字列に対するバイトレベルのビューを公開します。std.mem.span("zero") の形はバイトに対する Span<u8> を返します——パース、ハッシュ、バイト単位の比較で便利です。

Void

Void は Zero の「有用な戻り値はない」型です。副作用のために存在する関数が使います。

pub fun main(world: World) -> Void raises {
    check world.out.write("hello\n")
}

main は何かを書いて返ります。返す値がないので、型は Void です。World に触れるほとんどの関数で Void を見かけます——結果ではなくエフェクトのために選ばれているからです。

数値リテラルのアンダースコア

長い数値リテラルは視覚的な区切りとしてアンダースコアを使えます。コンパイラーは無視するので、純粋に読みやすさのための機能です。

let big   = 9_000_000_000_i64
let bytes = 1_048_576_u32     // 1 MiB

桁が数えにくくなったらどこにでも入れて構いません。

型付きリテラルサフィックス早見表

サフィックス
_i8 / _i16 / _i32 / _i64符号付き整数127_i8
_u8 / _u16 / _u32 / _u64符号なし整数255_u8
_usize / _isizeポインタサイズ0_usize
_f32 / _f64浮動小数点0.5_f32

周囲のコンテキストが型を確定させない場面で値を構築するときに役立ちます。

次回: 関数

プリミティブは、それを使って何かするものがなければ役に立ちません。次のドキュメントでは Zero の 関数 を扱います——宣言の仕方、値の返し方、そしてそれらを組み合わせて本物のプログラムを構築する方法です。

よくある質問

Zero にはどんなプリミティブ型がありますか?

Zero には、サイズ付き符号付き整数 i8i16i32i64、符号なし整数 u8u16u32u64、ポインタサイズ整数 usizeisize、浮動小数点 f32f64boolcharString、そして有用な値を返さない関数のための Void が標準で備わっています。

Zero のデフォルトの整数型は?

42 のようなサフィックスのない整数リテラルは、コンテキストが別の型を強制しない限りデフォルトで i32 になります。特定の幅を使うには 42_u842_i64 のようにサフィックス付きリテラルを書くか、let count: u8 = 42 のようにバインディングの型を明示的に注釈します。

Zero には専用の文字列型がありますか?

はい。"hello" のような文字列リテラルにはビルトインの文字列型があり、標準ライブラリは通常それをバイトのシーケンス(多くは UTF-8)として扱います。低水準のバイト操作には、標準ライブラリがスパンとバイトレベルのユーティリティを公開します。文字レベルの操作には、個々のスカラー値のための char があります。

Zero における Void の意味は?

Void は、有用な値を生成しない関数の戻り値型です——副作用のためだけに存在する関数のもの。慣用的な pub fun main(world: World) -> Void raises のシグネチャは、main が値を生成するためではなく I/O を行って終了するために存在するので、Void を使います。

Zero の i32 と u32 の違いは?

i32 は符号付き 32 ビット整数で、範囲は −2,147,483,648 から 2,147,483,647 です。u32 は符号なしで範囲は 0 から 4,294,967,295。負の値が意味を持つ場合は符号付きを、負の値がバグになる場合(カウント、インデックス、サイズなど)は符号なしを使いましょう。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める