# Rust との違い

Kagari の構文は Rust の部分集合にいくつかの追加を加えたもので、本リファレンスに別の記述がない限り、構文の意味は Rust と同じです。この章では、Rust のプログラマーが知っておくべき違い、つまり何がなく何がその代わりになるのか、なじみのある構文がどこで違う振る舞いをするのかをまとめます。

## 言語にないもの {#what-is-not-in-the-language}

| Rust の機能 | ない理由、または代わりのもの |
| ----------- | ---------------------------- |
| ライフタイム、借用チェッカー、ムーブ、`Drop` | 値はコピーされ、参照は共有ポインターです。[値、参照、クロージャ](./values.md)を参照 |
| 浮動小数点数（`f32`、`f64`） | 浮動小数点数は `Eq` ではなくプラットフォームによって結果が異なりますが、画面は厳密に比較できなければなりません。`Decimal`（`0.5`）か `Rat` を使います。[数値](./numbers.md)を参照 |
| `as` キャスト | `x.into()`（損失なし、検査付き）と `x.saturate()`（範囲内に丸める）。`as` は構文解析されますが `E2019` です |
| ユーザー定義トレイト、`impl Trait for T`、`derive` | 存在するのは標準ライブラリの `#[builtin]` トレイトだけです（`E1012`、`E1023`）。`Eq` は自動的に実装されます。[言語トレイト](../special/traits.md)を参照 |
| `dyn Trait`、`impl Trait` 型、`where` 句、`<T as Trait>::f` | 標準トレイトしかありません。境界はジェネリクスパラメーターの並びに書きます（`T: Eq`） |
| マクロ（`macro_rules!`、`println!`、`vec!` など） | テンプレートやインクルードが担っていたことは関数とシーンで書けます。[フォーム](./forms.md)は構文に組み込まれた固定の集合です |
| `unsafe`、生ポインター、`extern` | 不要です。コードは検証済みの VM で実行されます |
| `async`、スレッド | ステップでの物語の中断は言語に組み込まれています。[ステップ](../concepts/steps.md)を参照 |
| `goto`、位置としてのラベル | 構造化された制御フローだけです。[制御フローとループ](./control-flow.md#no-goto)を参照 |
| `char`、バイト文字列、生文字列、`&str` | 文字列リテラルは `Text` です。`String` は実行時の文字列です |
| `Box`、`Rc`、`HashMap`、スライス | 配列 `[T; N]` と `Vec<T>`。すべての型は値型です |
| `Iterator` トレイト、`.iter()`、`.map(…)` の連鎖 | `for` ループで配列、`Vec<T>`、整数の範囲を直接反復します |
| `move` クロージャ | クロージャは常に値でキャプチャします |
| `let … else`、`if let … && …` の連鎖、ラベル付きブロック | `match`、入れ子の `if let`、ループのラベル |
| スライスパターン、`&` パターン、`ref`、`name @ pattern` | 使えるパターンの形は[パターン](./patterns.md#pattern-forms)を参照 |
| 構造体更新構文 `S { a: 1, ..base }` | すべてのフィールドを書きます |
| `#[derive]`、`#[cfg]`、`#[test]` などの属性 | `#[scene]`、`#[entry]`、`#[must_use]`、`#[shader_arg]`（と標準ライブラリの `#[builtin]`）だけです。それ以外の属性は `E1006` です。[属性](../special/attributes.md)を参照 |
| `pub(crate)`、`pub(super)` | `pub` だけです |
| 値としての開いた範囲 `a..`、`..b`、`..=b`、`..` | 範囲式には両端が必要です（`E2030`）。パターンでは `a..` と `..=b` は使えますが、`..b` はありません。[範囲パターン](./patterns.md#range-patterns)を参照 |

## 振る舞いが異なるもの {#things-that-work-differently}

### 関数種別 {#function-kinds}

すべての関数は種別を持ちます。`fn`、`pushdown fn`、`const fn` のいずれかで、`pushdown fn` は `#[scene]` にもできます。種別によって、関数が何を呼べて何をできるかが決まります。`const fn` は純粋で、物語変数、設定、メタを読めません。[関数種別](../concepts/kinds.md)を参照してください。

### 数値 {#numbers}

- `Int<lo, hi>` はプリミティブの有界整数です。その算術は結果の範囲を計算し、複合代入はオーバーフローせず境界で飽和します。
- 整数リテラルと、範囲を含む別の `Int` 型への拡大を除き、整数型が暗黙に変換されることはありません。
- オーバーフローとゼロ除算は、定数のコードではコンパイルエラー、実行時にはパニックです。ラップアラウンドする算術はありません。
- `Int<lo, hi>` に対する `match` は、`lo` から `hi` までを網羅すれば `_` なしで網羅的です。

[数値](./numbers.md)を参照してください。

### 値と参照 {#values-and-references}

代入、引数渡し、戻り値はすべて値をコピーします。`&T` と `&mut T` は借用チェッカーのない共有ポインターで、`fn` と `const fn` のコードでは 1 つの場所への `&mut` が 2 つ同時に存在できます。`pushdown fn` の中では参照とクロージャは第二級で、渡して呼び出すことはできますが、格納したり返したりはできません。[値、参照、クロージャ](./values.md)を参照してください。

### 等価性と順序 {#equality-and-ordering}

`PartialEq` も `PartialOrd` もありません。`==` と `!=` は標準トレイト `Eq` を使い、構造的な等価性を持つすべての型が自動的にこれを実装します。クロージャは決して実装しません（`E2017`）。`<`、`>`、`<=`、`>=` は整数、`Int`、`Decimal`、`Rat` にだけあります（`E2015`）。

### static {#statics}

`static mut` は[物語変数](../concepts/story.md#story-variables)を宣言します。安全ですが、`pushdown fn` のコードからしか使えません（`E3007`）。不変の `static` に入れられるのは `Setting` か `Meta` のハンドルだけです（`E3011`）。それ以外の定数には `const` を使います。

### 束縛とパターン {#bindings-and-patterns}

- 束縛への代入は、最初の代入であっても変更として数えられます。初期化子のない `let` に後から代入するには `let mut` が必要です（`E3017`）。
- 構造体パターンでは `..` を書かずにフィールドを省略できます。
- `..b` はパターンではありません。`..=b` だけがあります。

### `?` 演算子 {#the-try-operator}

`?` は Rust と同じく `Option` と `Result` に使えますが、エラーの `From` 変換はありません。関数は同じエラー型の `Result` を返さなければなりません（`E2034`）。

### 文字列とテキスト {#strings-and-text}

文字列リテラルの型は `&str` ではなく、ゲームの定数の表示テキストである `Text` です。`.kix` ファイルでは、リッチテキストを [`t![…]`](./forms.md#t) で書きます。`String` は、`fn` のコードが実行時に組み立てるテキストの型です。

### ファイル {#files}

`.kis` ファイルには普通のコードを書きます。`.kix` ファイルでは[フォーム](./forms.md)も使えます。[ソースファイルとモジュール](./modules.md)を参照してください。
