Rust 100 Ex 🏃【4/37】 キャスト・構造体 (たまにUFCS)

前の記事

- [【0】 準備](https://qiita.com/namn1125/items/bd1b4cd028874189a3c1) ← 初回
- ...
- [【3】 可変・ループ・オーバーフロー](https://qiita.com/namn1125/items/4f57f8aede2f5201016f) ← 前回
- 【4】 キャスト・構造体  (たまにUFCS) ← 今回

<details><summary>全記事一覧</summary>

- [【0】 準備](https://qiita.com/namn1125/items/bd1b4cd028874189a3c1)
- [【1】 構文・整数・変数](https://qiita.com/namn1125/items/c776768baec89b8a0438)
- [【2】 if・パニック・演習](https://qiita.com/namn1125/items/13870965e8273bc87bce)
- [【3】 可変・ループ・オーバーフロー](https://qiita.com/namn1125/items/4f57f8aede2f5201016f)
- [【4】 キャスト・構造体 (たまにUFCS)](https://qiita.com/namn1125/items/227ed5bbedbb775c5d27)
- [【5】 バリデーション・モジュールの公開範囲 ～ → カプセル化！～](https://qiita.com/namn1125/items/46721cceccbfa9ec3c7a)
- [【6】 カプセル化の続きと所有権とセッター ～そして不変参照と可変参照！～](https://qiita.com/namn1125/items/442de7798d49f777384c)
- [【7】 スタック・ヒープと参照のサイズ ～メモリの話～](https://qiita.com/namn1125/items/780d80e4340f0e34dbf6)
- [【8】 デストラクタ(変数の終わり)・トレイト ～終わりと始まり～](https://qiita.com/namn1125/items/7247edde3b6bd0b85b25)
- [【9】 Orphan rule (孤児ルール)・演算子オーバーロード・derive ～Empowerment 💪 ～](https://qiita.com/namn1125/items/e565713b423301a80c76)
- [【10】 トレイト境界・文字列・Derefトレイト ～トレイトのアレコレ～](https://qiita.com/namn1125/items/9060faee2965f23e0e3d)
- [【11】 Sized トレイト・From トレイト・関連型 ～おもしろトレイトと関連型～](https://qiita.com/namn1125/items/b68990712d379a3d6a49)
- [【12】 Clone・Copy・Dropトレイト ～覚えるべき主要トレイトたち～](https://qiita.com/namn1125/items/c6f34945f331c7229746)
- [【13】 トレイトまとめ・列挙型・match式 ～最強のトレイトの次は、最強の列挙型～](https://qiita.com/namn1125/items/6b2cc31d6a47f9ffaff6)
- [【14】 フィールド付き列挙型とOption型 ～チョクワガタ～](https://qiita.com/namn1125/items/6fe69d1cab6c7936c698)
- [【15】 Result型 ～Rust流エラーハンドリング術～](https://qiita.com/namn1125/items/698aafaf22ec4bfd1bde)
- [【16】 Errorトレイトと外部クレート ～依存はCargo.tomlに全部お任せ！～](https://qiita.com/namn1125/items/9dae7b728fa0668e4102)
- [【17】 thiserror・TryFrom ～トレイトもResultも自由自在！～](https://qiita.com/namn1125/items/d67006a29b7ff5d6148c)
- [【18】 Errorのネスト・慣例的な書き方 ～Rustらしさの目醒め～](https://qiita.com/namn1125/items/705829027661a38e4a4f)
- [【19】 配列・動的配列 ～スタックが使われる配列と、ヒープに保存できる動的配列～](https://qiita.com/namn1125/items/9c49fd4c08f3e61896c7)
- [【20】 動的配列のリサイズ・イテレータ ～またまたトレイト登場！～](https://qiita.com/namn1125/items/6e4dede789c6de97f396)
- [【21】 イテレータ・ライフタイム ～ライフタイム注釈ようやく登場！～](https://qiita.com/namn1125/items/9a1224abf733f29a980a)
- [【22】 コンビネータ・RPIT ～ :dragon: 「 `Iterator` トレイトを実装してるやつ」～](https://qiita.com/namn1125/items/27fe20f2d60803c94357)
- [【23】 `impl Trait` ・スライス ～配列の欠片～](https://qiita.com/namn1125/items/7601d0268293ce7fcf28)
- [【24】 可変スライス・下書き構造体 ～構造体で状態表現～](https://qiita.com/namn1125/items/a9acc7dc2ca7c4c55cc3)
- [【25】 インデックス・可変インデックス ～インデックスもトレイト！～](https://qiita.com/namn1125/items/bd43375362af10ea8b42)
- [【26】 HashMap・順序・BTreeMap ～Rustの辞書型～](https://qiita.com/namn1125/items/a2806cded12fa719a1cb)
- [【27】 スレッド・'staticライフタイム ～並列処理に見るRustの恩恵～](https://qiita.com/namn1125/items/5a4a09172834063268b1)
- [【28】 リーク・スコープ付きスレッド ～ライフタイムに技あり！～](https://qiita.com/namn1125/items/34a0aacd4d40f9234aef)
- [【29】 チャネル・参照の内部可変性 ～Rustの虎の子、mpscと `Rc<RefCell<T>>`～](https://qiita.com/namn1125/items/861e72dbb4b837508948)
- [【30】 双方向通信・リファクタリング ～返信用封筒を入れよう！～](https://qiita.com/namn1125/items/46f03de967d0de46737e)
- [【31】 上限付きチャネル・PATCH機能 ～パンクしないように制御！～](https://qiita.com/namn1125/items/d7ae8a205ee969339401)
- [【32】 `Send`・排他的ロック(`Mutex`)・非対称排他的ロック(`RwLock`) ～真打 `Arc<Mutex<T>>` 登場～](https://qiita.com/namn1125/items/eee890dc8672e975e70c)
- [【33】 チャネルなしで実装・Syncの話 ～考察回です～](https://qiita.com/namn1125/items/cc8bee3871b727e564e3)
- [【34】 `async fn`・非同期タスク生成 ～Rustの非同期入門～](https://qiita.com/namn1125/items/9c32b730a283ad76c891)
- [【35】 非同期ランタイム・Futureトレイト ～非同期のお作法～](https://qiita.com/namn1125/items/c840d48f8f558613ec10)
- [【36】 ブロッキング・非同期用の実装・キャンセル ～ラストスパート！～](https://qiita.com/namn1125/items/39c139da3f1f26264353)
- [【37】 Axumでクラサバ！ ～最終回～](https://qiita.com/namn1125/items/bae492f823fbe60e9974)
- [【おまけ1】 Rustで勘違いしていたこと3選 🏄🌴 【100 Exercises To Learn Rust 🦀 完走記事 🏃】](https://qiita.com/namn1125/items/2a59f486cce30fd2b889)
- [【おまけ2】 【🙇 懺悔 🙇】Qiitanグッズ欲しさに1日に33記事投稿した話またはQiita CLIとcargo scriptを布教する的な何か](https://qiita.com/namn1125/items/8e552694b389c5b13b5e)
</details>

[100 Exercise To Learn Rust](https://rust-exercises.com/) 演習第4回になります！前半の2問はなんというか前回フライングしているというか...という感じですが、最後の1問は新章に入り構造体という大きめの話題になっています！

今回の関連ページ

- [2.9. Saturating arithmetic](https://rust-exercises.com/02_basic_calculator/09_saturating)
- [2.10. Conversions: as casting](https://rust-exercises.com/02_basic_calculator/10_as_casting)
- [3.1. Structs](https://rust-exercises.com/03_ticket_v1/01_struct)

では行きましょう！

# [[02_basic_calculator/09_saturating](https://github.com/mainmatter/100-exercises-to-learn-rust/blob/main/exercises/02_basic_calculator/09_saturating/src/lib.rs)] 飽和演算

- [2.9. Saturating arithmetic](https://rust-exercises.com/02_basic_calculator/09_saturating)

問題はこちらです。

```rust:lib.rs
pub fn factorial(n: u32) -> u32 {
    let mut result = 1;
    for i in 1..=n {
        // Use saturating multiplication to stop at the maximum value of u32
        // rather than overflowing and wrapping around
        result *= i;
    }
    result
}

#[cfg(test)]
mod tests {
    use crate::factorial;

    #[test]
    fn twentieth() {
        assert_eq!(factorial(20), u32::MAX);
    }

    // ...省略...
}
```

<details><summary>省略なし</summary>

```rust:lib.rs
pub fn factorial(n: u32) -> u32 {
    let mut result = 1;
    for i in 1..=n {
        // Use saturating multiplication to stop at the maximum value of u32
        // rather than overflowing and wrapping around
        result = result.saturating_mul(i);
    }
    result
}

#[cfg(test)]
mod tests {
    use crate::factorial;

    #[test]
    fn twentieth() {
        assert_eq!(factorial(20), u32::MAX);
    }

    #[test]
    fn first() {
        assert_eq!(factorial(0), 1);
    }

    #[test]
    fn second() {
        assert_eq!(factorial(1), 1);
    }

    #[test]
    fn third() {
        assert_eq!(factorial(2), 2);
    }

    #[test]
    fn fifth() {
        assert_eq!(factorial(5), 120);
    }
}
```
</details>

うーん... **[前回最後の問題](https://qiita.com/namn1125/items/4f57f8aede2f5201016f#02_basic_calculator08_overflow-%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%95%E3%83%AD%E3%83%BC)にてフライングしちゃってたみたいですね...** :sweat_smile: 

本当は本問題で [`u32::wrapping_mul`](https://doc.rust-lang.org/std/primitive.u32.html#method.wrapping_mul) を紹介するべきだったみたい...ただ、問題自体はこちらではなくて [`u32::saturating_mul`](https://doc.rust-lang.org/std/primitive.u32.html#method.saturating_mul) の方で実装してほしいようです。 `wrapping` は一周したらまた増えていく・減っていく演算(最後の繰り上がりを無視する)になっていますが、 `saturating` の方は最大値・最小値になったらそこで止まる演算(飽和演算)になっています。 [本編](https://rust-exercises.com/02_basic_calculator/09_saturating) ではCargo.tomlへの `overflow-checks` では指定できない挙動という理由で面白いとしているみたいですね。

## 解説

前回最後の別解の `u32::wrapping_mul` を `u32::saturating_mul` に置き換えるだけです。

```rust:lib.rs
pub fn factorial(n: u32) -> u32 {
    let mut result = 1u32;
    for i in 1..=n {
        result = result.saturating_mul(i);
    }
    result
}
```

前回別解紹介時には言っていなかった注意点としては、型推論の都合からか `let mut result` の段階で `result` の型が確定していないといけないようです[^typeguess]。模範解答では `let mut result: u32 = 1;` としていますが筆者は `1` 側を `1u32` として `u32` 型であることを表しています。どっちでも良いので好みが出る部分でしょう。

[^typeguess]: 明らかに分かりそうでも型推論が働かない時は意外とありますが、こういう場合は人間にとってもちゃんと注釈しておいた方が良かったりしますね。筆者的には程よいバランスだと思います。(慣れているだけ説はある)

# [[02_basic_calculator/10_as_casting](https://github.com/mainmatter/100-exercises-to-learn-rust/blob/main/exercises/02_basic_calculator/10_as_casting/src/lib.rs)] キャスト

- [2.10. Conversions: as casting](https://rust-exercises.com/02_basic_calculator/10_as_casting)

問題はこちらです。

```rust:lib.rs
// TODO: based on what you learned in this section, replace `todo!()` with
//  the correct value after the conversion.

#[cfg(test)]
mod tests {

    #[test]
    fn u16_to_u32() {
        let v: u32 = todo!();
        assert_eq!(47u16 as u32, v);
    }

    #[test]
    fn u8_to_i8() {
        // The compiler is smart enough to know that the value 255 cannot fit
        // inside an i8, so it'll emit a hard error. We intentionally disable
        // this guardrail to make this (bad) conversion possible.
        // The compiler is only able to pick on this because the value is a
        // literal. If we were to use a variable, the compiler wouldn't be able to
        // catch this at compile time.
        #[allow(overflowing_literals)]
        let x = { 255 as i8 };

        // You could solve this by using exactly the same expression as above,
        // but that would defeat the purpose of the exercise. Instead, use a genuine
        // `i8` value that is equivalent to `255` when converted from `u8`.
        let y: i8 = todo!();

        assert_eq!(x, y);
    }

    #[test]
    fn bool_to_u8() {
        let v: u8 = todo!();
        assert_eq!(true as u8, v);
    }
}
```

型変換の問題です。本編では暗黙キャストをしてくれないRustにてどうやって明示キャストさせるかを書いています。テスト内に直書きさせるのか...

コメントが多いので要約しておきます。

- 習った内容を使って `todo!()` を置き換えてね！
- コンパイラは賢いので `255` が `i8` に収まらないことを知っています。そのためエラーを出すでしょう
    - 意図的にオフにしてこの悪いキャストを行うことは可能です
    - これをコンパイルエラーとして検出できるのはここに書かれている数字はリテラルだからです。変数の場合は動的エラーになるでしょう
- 上記の方法を使わず、 **`i8` での本物の値** を使って解いてね！

## 解説

最初の方はシンプルに置き換えるだけですね。

```rust:lib.rs
#[test]
fn u16_to_u32() {
    let v: u32 = 47;
    assert_eq!(47u16 as u32, v);
}
```

2つ目は `i8` のフルビットで2の補数表現が使われ、

そして $01 + \mathrm{FF} = 01 \ 00 \equiv 0$ より $\mathrm{FF} \equiv -1$ [^tekito] であるから $255 = \mathrm{FF} \equiv -1$ ...

[^tekito]: テキトー表記で厳密な数式表現じゃありません...伝われ

```rust:lib.rs
#[test]
fn u8_to_i8() {
    #[allow(overflowing_literals)]
    let x = { 255 as i8 };

    let y: i8 = -1;

    assert_eq!(x, y);
}
```

最後は真偽値から `u8` へのキャスト... 🤮

```rust:lib.rs
#[test]
fn bool_to_u8() {
    let v: u8 = 1;
    assert_eq!(true as u8, v);
}
```

なんで吐いてしまったかというと **真偽値型から整数型へのキャストをしたい場面というのはない** ためです。低レイヤーでバイナリを扱いたいならRustの真偽値ではなくもっと適切な構造体なりなんなりがありそうですし、そうではなく一般用途でキャストが要るのでしたら、そもそも真偽値で表していること自体が設計誤りな気がします。

`as` によるキャストは使うには使いますが、数値型間でオーバーフローの心配がない場面ぐらいでしか使わないです。構造体間でキャストしたい場合は...[本編で後ほど登場する](https://rust-exercises.com/05_ticket_v2/13_try_from)らしいのでここでは触れないでおきます。が、ともかく `as` はあんまり型変換には使用しないです。(それよりは名前空間で `use` する時にエイリアスつける時の方が使われてそう)

# [[03_ticket_v1/01_struct](https://github.com/mainmatter/100-exercises-to-learn-rust/blob/main/exercises/03_ticket_v1/01_struct/src/lib.rs)] 構造体

3章では JIRA のようなチケットシステムを模倣するのが題材らしく、構造体や、いよいよ本章で **所有権** の話が登場するようです...！楽しくなりそう...

- [3.1. Structs](https://rust-exercises.com/03_ticket_v1/01_struct)

さっそく最初の問題はこちらです。

```rust:lib.rs
// Define a struct named `Order` with the following fields:
// - `price`, an unsigned integer
// - `quantity`, an unsigned integer
//
// It should also have a method named `is_available` that returns a `true` if the quantity is
// greater than 0, otherwise `false`.

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_order_is_available() {
        let order = Order {
            price: 100,
            quantity: 10,
        };
        assert!(order.is_available());
    }

    #[test]
    fn test_order_is_not_available() {
        let order = Order {
            price: 100,
            quantity: 0,
        };
        assert!(!order.is_available());
    }
}
```

長いですが、テスト部分も参考になるため折りたたまず全て載せました。

コメントを要約すると次のような感じです。

- `Order` という名前の構造体を定義してください
    - 符号なし整数 `price` フィールドを持ちます
    - 符号なし整数 `quantity` フィールドを持ちます
- また `Order` 構造体は `is_available` というメソッドを持ち、 `quantity` が0より大きければ `true` を、そうでなければ `false` を返します

## 解説

```rust:lib.rs
struct Order {
    price: u32,
    quantity: u32,
}

impl Order {
    fn is_available(&self) -> bool {
        self.quantity > 0
    }
}
```

うーん、数行のコードに色々な要素が詰まっている...`struct Order {...}` の部分で `Order` という構造体を用いることができ、 `impl Order {}` ブロックの中にて関数を定義することで、作成した構造体に対して `is_available` というメソッドを呼び出せるようになります。

```rust:Rust
let order = Order {
    price: 100,
    quantity: 10,
};

if order.is_available() {
    println!("Available order.");
}
```

後ほど登場する所有権によってリソース所在が明確化されるなど、筆者がRust好きな理由は色々ありますが、特にこの `impl` キーワード内での構造体へのメソッド定義方法も好きな理由だったりします。

いい機会ですのでちょっとオタク語りしちゃいますね...

## UFCS

あれは遡ること6年前ぐらい... [Nim](https://nim-lang.org/) という言語が少し流行り、 [Qiita上で見かけた](https://qiita.com/rigani/items/6e87c7cee6903ed65ed2) のをきっかけに筆者も触ってみたのですが、その時に出会ったのが [UFCS (Uniform Function Call Syntax)](https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax) という文法でした[^dlang]。

[^dlang]: 一応補足しておくとUFCSの初出はNimではありません。[先に挙げたリンク先](https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax)を読む限りD言語でいいのかな...？こういう歴史系の話はマサカリが怖い...

[Nim basics ufcs.nim](https://narimiran.github.io/nim-basics/#_calling_the_procedures:~:text=of%20multiple%20procedures%3A-,ufcs.nim,-proc%20plus) (少し改変)

```nim:Nim
proc plus(x, y: int): int =
  echo "plus(", x, ", ", y, ")"
  return x + y

proc multi(x, y: int): int =
  echo "multi(", x, ", ", y, ")"
  return x * y

echo multi(plus(1, 2), 3)

# ...？！
echo 1.plus(2).multi(3)

let
  a = 2
  b = 3
  c = 4

echo a.plus(b) == plus(a, b)
echo c.multi(a) == multi(c, a)


echo a.plus(b).multi(c)
echo c.multi(b).plus(a)
```

それまでメソッドの概念をクラスベースオブジェクト指向言語 (JavaやC#など。以降クラスベースOOPと呼ぶ) でしか知らなかった筆者は衝撃を受けました。

**「組み込み型へ自分でメソッドを生やせるのか？！」**

と。

実際はそういうわけではなく、ただの関数を定義していて、それをメソッド**風**に呼び出しています。

```nim:書き方が異なるだけで全く同じ意味(糖衣構文)
multi(plus(1, 2), 3) == 1.plus(2).multi(3)
```

「クラスとして定義しないとドットによるメソッド呼び出しという(高尚な)記法は使えないんだろうな」という固定観念に囚われていたために[^clangmethod]目から鱗をこぼさずにはいられませんでした。

[^clangmethod]: C言語なら構造体のフィールドに関数ポインタを設けることで擬似的に、JSでも構造体のフィールドに関数をもたせることで擬似的に、ぞれぞれメソッドのような書き方が可能ですが、どちらにせよクラスや構造体の方で定義する必要があり、後から拡張することは叶わないんだろうなと思っていた感じです。

メソッド記法が使えると以下のようなメリットがあります！

- メソッドチェーンを用いて流れるように処理を書ける
- IDEで変数に対して補完を効かせることができる

そしてUFCSのお陰で、オブジェクト指向パラダイムで最も有能な要素である[^oopkagekiha]メソッド記法が、上記に示したような **ただの糖衣構文である** という、とてもわかりやすい形で取り入れられています。

[^oopkagekiha]: それ以外のメリットといえばカプセル化とかでしょうか？この辺言及すると怖い人達がたくさんマサカリを投げてくるのでクラスベースOOPは正直苦手です...

UFCSの世界には関数定義しかなく、クラスベースOOPにあるようなインスタンスメソッド、クラスメソッド、 `this` キーワード、オーバーライドやスーパークラスみたいな複雑な概念と戦わなくても、メソッド記法のメリットが享受できるのです！

## RustとUFCS

ここで先程のメソッド定義に戻ってみましょう。Rustも、UFCSに近い[^ufcslike]文法を提供しています！

[^ufcslike]: RustのものはUFCSと[呼ばれたり呼ばれなかったり](https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax#:~:text=the%20cppfront%20compiler.-,Rust%20usage%20of%20the%20term,-%5Bedit%5D)しています。UFCSのUは統一(Uniform/Unified)のUですが、記事執筆時点ではプログラミング言語間ではUFCSに近い概念に対して統一された名前はないように感じます...いっそのことドット記法とでも呼べばと言っていた人がいるのですが、自分もそう思います。

```rust:lib.rs
struct Order {
    price: u32,
    quantity: u32,
}

impl Order {
    fn is_available(&self) -> bool {
        self.quantity > 0
    }
}
```

前提として、 `is_available` はOOPでいうメソッドである以前に構造体 `Order` の **関連関数** と呼ばれるもので、 `Order::is_available` というパスでアクセスできる **ただの** 関数になっています。よって以下のようにして呼び出すことができます(まだここまでの演習で出てきていない不変参照 `&` が登場していますが、とりあえず無視してください)。

```rust:Rust
let order = Order {
    price: 100,
    quantity: 10,
};

let res = Order::is_available(&order);
```

`fn is_available(&self) {...}` の第一引数になっている `&self` はレシーバと呼ばれ、 `self: &Order` の糖衣構文になっています。また特別な意味も持っており、 `self` を用いて定義された関連関数こそが **メソッド風に呼び出せる** ようになっていて(UFCS要素)、 よってこの場合 `is_available` はRustでも単に「メソッド」と呼ばれます！

```rust:Rustのメソッド呼び出し
let res = order.is_available(); // Order::is_available(&order) と同じ意味！
```

Rustにおいて、 `impl` ブロックで関連関数及びメソッドを定義できる方式になっているのは、以下のような特徴・メリットがあると筆者は考えています！

- `impl` ブロックとして構造体定義とは独立した部分で宣言されている
    - **構造体は構造体にすぎない** (クラスではない)と認識でき、シンプルに考えられる
    - 大規模になった場合、メソッド部分だけ別な場所やファイルに切り出せる(柔軟性がある)[^impltrait]
- 第一引数 `self` の存在
    - メソッドは **関連関数の第一引数がその構造体であるだけの関数にすぎない** と認識でき、シンプルに考えられる
    - `self` をクラスベースOOPにおける `this` 変数のような複雑な存在ではなく、 **その構造体型の、ただの値に過ぎないもの** と認識できる
    - レシーバ `self` の部分は構造体本体だったり後ほど登場する不変参照だったり可変参照だったりするが、すなわち身分を明記できる
        - 逆に言えば `self` を使ったUFCSのような記法はRustのその他のパラダイムとも相性がいい

[^impltrait]: ただこの場合は直接ではなく何かしらのトレイトを `impl` する形のほうが良さそうですね。

まとめると `impl`ブロックでメソッド定義を行うこの決まりは「 **認知負荷が少ない** 」記法だと言えるわけです。このシンプルさが筆者がRustを好む理由の一つになっています！

:::note
**UFCSっぽい言語たち**

Rustだけではなく先に挙げたNimを含め、UFCS、あるいはUFCSモドキにメソッドを定義できる言語は実は結構居たりします。筆者が認識しているものだと以下です。

- D言語
- Rust
- Nim
- Go
- Python

そう、クラスベースOOPではありますが実はPythonもこの点で似ているんですよね...UFCSを知ってからPythonのメソッド定義を見直してみると、Rustと同様に `self` レシーバが潜んでいるのを発見できます！

```python:Python
class Order:
    price: int
    quantity: int

    def __init__(self, price: int, quantity: int):
        self.price = price
        self.quantity = quantity

    def is_available(self) -> bool:
        return self.quantity > 0

order = Order(100, 10)
print(order.is_available())

# 実はPythonも以下のようにメソッドを関連関数ライクに呼べる
print(Order.is_available(order))
```

というかRustとほぼ同じ構造であることに気づきます...！

<details><summary>Rust側をさらにこのPythonコードに近づけた例</summary>

```rust:Rust
struct Order {
    price: u32,
    quantity: u32,
}

impl Order {
    fn new(price: u32, quantity: u32) -> Self {
        Self {
            price,
            quantity,
        }
    }

    fn is_available(&self) -> bool {
        self.quantity > 0
    }
}

fn main() {
    let order = Order::new(100, 10);
    
    println!("{}", order.is_available());
    
    println!("{}", Order::is_available(&order));
}
```

`new` はただの関連関数です！Rustには構造体のコンストラクタにあたる文法はなく、それにあたる関数には慣例的に `new` という名前をつけるという文化があります！これもシンプルさに寄与している推しポイントでしたが、盛り込むと長くなるためここに書きました。(もとい、次回以降取り扱いがありそう)
</details>

こんな感じで、メソッドを、「レシーバを明記しているただの関数である」という扱いにしている言語、最近流行ってきていると思います...！UFCS以外に適切な呼称がない一方、厳密にはUFCSではないと言われているため、筆者はこの流行りにもっと適切な名称がないかと日々モニョっております...
:::

---

以上、めちゃくちゃ語ってしまいましたが、それだけこの `impl` ブロックに面白さがあるわけです。 `impl` ブロックは本章にとどまらずこの後も [トレイト](https://rust-exercises.com/04_traits/01_trait) 等いろんな場所で登場すると思われますが、そのたびに「良くできた書き方だなぁ」と思うこと請け合いです！

では次の問題に行きましょう！

次の記事: [【5】 バリデーション・モジュールの公開範囲 ～ → カプセル化！～](https://qiita.com/namn1125/items/46721cceccbfa9ec3c7a)