Kagari
キーワードを入力してドキュメントを検索します。

特殊な型、トレイト、属性

ビルトイン型

ゲームが使う型の大半は std の普通の宣言で、皆さんの型と同じく Kagari で書かれています。ただし一部の型はコンパイラが名前で知っています。専用の構文や専用の検査があるか、あるいは見える表現をまったく持ちません。この章ではそれらを列挙し、それぞれの何が特別なのかを説明します。不透明かどうか、有限型かどうか、Eq かどうか、どの関数種別で役立つか、コピーが何を意味するか、です。メソッドは STD Reference にあります。

Kagari のすべての型は値セマンティクスを持ちます。代入、引数渡し、戻り値は値をコピーします(値、参照、クロージャを参照)。以下のハンドル型ではコピーされる値がハンドルなので、両方のコピーは同じ保存先を指します。

概要

型定義有限Eq主な種別STD のページ
bool、()言語はいはいすべて—
Int<lo, hi>言語はいはいすべて—
u8 … u128、i8 … i128、usize、isize言語いいえはいfn、const fn—
Rat、Decimal#[builtin] 構造体いいえはいfn、const fnstd
String#[builtin] 構造体いいえはいfn、const fnstd
Text#[builtin] 構造体はいはいすべてstd::narrative::text
ImageAsset、AudioAsset、VoiceAsset、VideoAsset、FontAsset#[builtin] 構造体はいはいすべてstd
ColorShader<A>、MixShader<A>、TextureShader<A>、MaskShader<A>、LocalMotionShader<A>、TransitionalMotionShader<A>#[builtin] 構造体いいえはいconst fnstd::screen::shader
Vec<T>#[builtin] 構造体いいえT: Eq ならfn、const fnstd
Range<T>構造体T が有限ならT: Eq ならすべてstd
Option<T>、Result<T, E>列挙型型引数が有限なら型引数が Eq ならすべてstd
Setting<T>、Meta<T>#[builtin] 構造体いいえいいえfn(後述)std::system、std::narrative
Narrative#[builtin] 構造体いいえいいえfnstd::narrative
Screen#[builtin] 構造体いいえはいconst fnstd::screen
Entity、Prop<T>、ImageLayer、LabelLayer、MovieLayer、Hud、ChoiceMenu、Camera、Channel#[builtin] 構造体いいえいいえconst fnstd::screen、std::screen::audio
Change<T>、Swap、ChannelChange#[must_use] #[builtin] 構造体いいえいいえconst fnstd::screen、std::screen::audio
Element、Placed#[builtin] 構造体いいえいいえfnstd::ui
Arm、Divergence#[builtin] 構造体いいえいいえfnstd::narrative、std::system::saves
Renderconst fn(Screen) -> Screen の型エイリアスはいはいすべてstd::screen
Duration構造体いいえはいすべて(物語では定数として)std::time
関数ポインタ言語fn 以外の種別ならはいすべて—
クロージャ Fn(…)言語いいえいいえすべて(物語では第二級)—

「有限」は、pushdown fn がその型の値を実行時に保持できるかどうかを決めます(E3008)。どの型の定数式も、コンパイル時に畳み込まれるので物語の中に書けます。

不透明なビルトイン型

#[builtin] 付きで宣言された構造体は、コンパイラとエンジンが実装します。見えるフィールドはありません。

  • 構造体リテラルを書くことも、フィールドを読むことも、パターンで分解することもできません。値は std の関数とメソッド、リテラル(Text、Decimal)、またはエンジン(Narrative)からのみ得られます。
  • Eq になるのは std が impl Eq でそう宣言した場合だけです。構造的な Eq の規則は中を見ません(言語トレイトを参照)。
  • 有限型になるのは Text とアセット型だけです。その他のビルトイン型はすべて無限として扱われます。
  • 表現は .kagari ファイルに含まれないため、ゲームを壊さずにエンジンのバージョン間で変えられます。

ビルトイン型を宣言できるのは std だけです(E1008)。大半はプレリュードに入っていますが、画面状態の型(Entity、Prop<T>、各レイヤーなど)は入っていません。これらは Screen のメソッドから &mut 参照として受け取るもので、名前を書くことはまれだからです。

Text

Text は定数テキストです。プレーン("Mio")またはリッチ(ルビ、テキスト効果、埋め込みを含む t![…] で作るもの)です。文字列リテラルの型は String ではなく Text です。

kis
const NAME: Text = "Mio";
  • 有限。 物語の中の Text の値はプログラムの定数テキストなので、物語変数や pushdown fn の引数・戻り値を Text にできます。
  • エントリーシーンでは不可。 fn のコードは to_text で実行時に新しいテキストを作れるため、エントリーシーンの引数型と戻り値型に Text を含めることはできません(E3009)。
  • 埋め込み。 t![…] の中の {expr} は to_text(expr) の呼び出しで、expr: T に T: ToText を要求します。pushdown fn の中では、有限な実行時の値に対する to_text は他の const fn 呼び出しと同じく表化されるので、台詞は物語の状態の有限な関数のままです。
  • Eq:はい。

String

String は fn のコード向けの実行時文字列です。有限型ではなく、Eq と ToText を実装します。

暫定。 現在の std には String を作る関数も変更する関数もありません。ゲームが表示するテキストは Text です。

アセット型

ImageAsset、AudioAsset、VoiceAsset、VideoAsset、FontAsset は、ゲームと一緒にパックされるファイルを指します。6 つのシェーダー型(ColorShader<A> など)も同様で、引数の型が A である 1 つのロールの WGSL ファイル(.wgsl)を指します。値は asset または system_font の定数呼び出しでのみ作られます。

kis
const CG_001: ImageAsset = asset("cg_001.png");
const THEME: AudioAsset = asset("bgm/theme.ogg");
const GOTHIC: FontAsset = system_font("msgothic.ttc");
  • asset::<A> の型引数は定数の型から推論され、Asset を実装していなければなりません。
  • 引数は文字列リテラルで(E2028)、空でなく(E1028)、アセットディレクトリの中で(E1029)その予約されたディレクトリ system-fonts と std の外を指す必要があります(E1032)。ファイルがなければ E1027 です。system_font には独自の規則があります(E1030、E1031)。STD Reference の std を参照してください。
  • 有限。 ファイルのアセット型の値はちょうどプログラムのアセット定数なので、物語はそれを保持でき、アセット名の綴り間違いは実行時の失敗ではなく名前解決のエラーになります。シェーダー型は有限型ではありません。シェーダーを使うのはレンダーで、物語ではありません。
  • Eq:はい。
  • 効果値が保持する、ロールを持たないシェーダーファイルの識別子 ShaderAsset は、Asset ではなく、プレリュードにもありません。ゲームが名前で書くことはありません。std::screen::shader を参照してください。

Setting<T> と Meta<T>

設定とメタフィールドは、セーブの外に保存される永続的なグローバル値です。それぞれハンドルを保持する不変の static で宣言します。

kis
static MUSIC: Setting<Volume> = setting(volume(60));
static CLEARED_AZUSA: Meta<bool> = meta(false);
  • 不変の static は Setting<T> か Meta<T> を保持しなければならず(E3011)、setting(…) と meta(…) は static の初期化子としてのみ呼べます(E4007)。初期化子は、保存ファイルに値がないときに使われる値です。
  • ハンドル自体は値です。関数に渡したり、Settings のようなレコードに格納したりできます。コピーするとハンドルがコピーされ、両方のコピーは同じ保存値を読み書きします。
  • 種別。 get と set は fn です。Meta::write は pushdown fn で、物語はメタを書くだけで読みません。const fn は Setting のハンドルを値としてのみ使えます(Entity::gate に渡す場合など)。そこで get を呼ぶと E3001 です。const のコードはメタフィールドにまったく言及できません(E3013)。
  • 有限型ではなく、Eq でもありません。

ゲームシステムとレンダーの中の設定を参照してください。

Narrative

Narrative は、実行中の物語をシステムから見る唯一の窓です。エンジンはこれをゲームビュー(System::game、fn(Narrative) -> Element)とゲームオーバーレイ(fn(Narrative) -> GameOverlay)にだけ渡します。表現は隠されているので、システムのコードは物語変数を読めません。メソッドはすべて fn で、読み取りはリアクティブです。コピーは同じ実行中のゲームを指します。有限型ではなく、Eq でもありません。

Screen とその部品

Screen は、ステップが表示する画面とそのステップのタイムラインです。すべてのレンダーの入力であり出力です。メソッドはすべて const fn です。

  • 値。 レンダーは直前の画面のコピーを受け取り、新しい画面を返します。コピーを変えても呼び出し元の画面は変わりません。
  • 部品。 Entity、Prop<T>、ImageLayer、LabelLayer、MovieLayer、Hud、ChoiceMenu、Camera、Channel は画面の部品です。screen.entity(id) や screen.music() などのメソッドから &mut 参照として受け取り、その参照を通した変更はその画面を変えます。
  • 保留中の変更。 Change<T>、Swap、ChannelChange は change、clear、stop が返す保留中の変更です。これらは #[must_use] で、apply_animation を呼ぶまで何も起きません。捨てられた保留中の変更は警告 W3023 になります。
  • Screen は Eq なので、コンパイラは一貫性のために画面を比較できます。部品は Eq ではありません。いずれも有限型ではありません。

Element と Placed

Element はエンジンがレイアウトする UI 要素ツリーで、Placed は layer![…] の中に配置された要素です。どちらも UI フォームと std::ui の関数で作られ、それらはすべて fn です。有限型ではなく、Eq でもありません。

Arm と Divergence

Arm は現在の選択肢の選べるアームで、Narrative::menu から読み、Narrative::select に渡し返します。Divergence は、セーブがもうプログラムに合わないときの nav::load のエラーです。どちらも fn のコードにしか現れません。有限型ではなく、Eq でもありません。

数値

型定義有限備考
Int<lo, hi>言語のプリミティブはい整数 lo..=hi。lo と hi は lo <= hi を満たす定数の i64 値です(E2004)。物語が実行時に保持できる唯一の整数型です
u8 … u128、i8 … i128、usize、isize言語のプリミティブいいえRust の演算子を持つ Rust の整数
Decimalstd の #[builtin] 構造体いいえ正確な十進数。小数点を含むリテラル(0.5)は Decimal です。浮動小数点数の代わりです
Ratstd の #[builtin] 構造体いいえ正確な有理数。リテラルはなく、Rat::new(num, den) と書きます

いずれも Eq で、整数、Rat、Decimal には順序があります(<、<= など)。整数型どうしは算術で混ぜられず(E2014)、変換は Integer のメソッド into と saturate だけで行います。as キャストはありません(E2019)。算術、リテラルの型付け、飽和、オーバーフローは数値で説明します。

Vec<T>

Vec<T> は fn と const fn のコード向けの可変長リストです。他のすべての型と同じく値です。push と set は呼び出した場所を変え、コピーには影響しません。

  • v[i] で任意の整数型の添字を使ってアクセスでき、for x in v で反復できます。どちらも Vec<T> と配列に対して言語に組み込まれています。
  • 範囲外の get は None を返し、範囲外の set は評価エラーです(コンパイル時評価では E4005)。
  • 有限型ではありません。T: Eq なら Eq です。

Range<T>

Range<T> は公開フィールド start、end、inclusive を持つ std の普通の構造体です。コンパイラは二つの場所でこれを知っています。

  • 範囲式。 a..b と a..=b は Range<T> を作ります。T は両端がともに変換できる型で、0..7 は Range<Int<0, 7>> です。範囲の値になるのは a..b と a..=b だけで、a..、..b、.. などの他の形は E2030 です。パターンには独自の範囲の形(a..、..=b、a..b、a..=b)があります。範囲パターンを参照してください。
  • for ループ。 for は T が整数型の Range<T> を反復します(そうでなければ E2031)。pushdown fn の中では両端が定数式でなければなりません(E3006)。

Option<T> と Result<T, E>

どちらも std の普通のジェネリックな列挙型で、プレリュードはそのバリアント None、Some、Ok、Err をインポートします。コンパイラは ? 演算子のためにこれらを知っています。Option に対しては Option を返す関数が、Result に対しては同じエラー型の Result を返す関数が必要です(E2034)。エラーの変換はありません。型引数が有限なら有限で、型引数が Eq なら Eq です。

関数ポインタ型とクロージャ型

関数の型は呼び出すコードの種別を持つので、呼び出し規則はポインタとクロージャを通しても成り立ちます。

型保持するもの有限対応するクロージャ型
fn(A) -> B名前付きの fnいいえFn(A) -> B
const fn(A) -> B名前付きの const fn、または何もキャプチャしないクロージャはいconst Fn(A) -> B
pushdown fn(A) -> B名前付きの即時手続きはいpushdown Fn(A) -> B
scene fn(A) -> B名前付きのシーンはいなし
Fn(A) -> B、const Fn(A) -> B、pushdown Fn(A) -> Bその種別のクロージャまたは関数いいえ—
  • 名前付きの関数は、ちょうど自分の種別のポインタ型またはクロージャ型に型強制されます。何もキャプチャしないクロージャは自分の種別のポインタに型強制されますが、キャプチャするクロージャはできません(E2036)。ポインタは同じ種別のクロージャ型に型強制されます。
  • pushdown と scene がキーワードになるのは fn の直前(および Fn の直前の pushdown)だけです。
  • 有限。 物語の種別または const のポインタは有限です。その値はプログラムの有限個の名前付き関数だからです。クロージャは決して有限型ではなく、物語の中では第二級です。
  • Eq。 関数ポインタは同一性で比較されます。クロージャは決して Eq ではありません(E2017)。

Render

kis
pub type Render = const fn(Screen) -> Screen;

std::screen とプレリュードにある Render は新しい型ではなくエイリアスです。レンダーはステップ前の画面からステップ後の画面への const fn で、ステップはこれを render 属性として受け取ります。const fn のポインタなので Render は有限で Eq であり、Render が期待される場所には何もキャプチャしないクロージャをその場で書けます。レンダー関数を参照してください。

kis
const fn clear_background(mut screen: Screen) -> Screen {
screen.background().clear().apply_animation(fade(ms(500)));
screen
}
const CLEAR: Render = clear_background;

Duration

kis
pub struct Duration { pub ms: u32 }

Duration は std::time の普通の構造体で、ビルトイン型ではありません。ここに載せるのは、std のあらゆる時間が整数ミリ秒の Duration だからです。単位付き文字列やフレーム数はありません。プレリュードには Duration、ms(n)、secs(n) があります。

  • u32 を保持するので有限型ではありません。物語は持続時間を、レンダーの中の fade(ms(500)) のような定数式でのみ使います。
  • Eq:はい(構造的に)。
  • div は切り捨てます。ms(1000).div(3) は ms(333) です。u32 ミリ秒に収まらない持続時間は、secs、plus、times で作られた場合も画面のタイムラインで到達した場合も、コンパイル時評価で E4013 になります。

最終更新日 2026年10月29日