1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Keep Rust Simple: Rustが持たない意外な10の機能

Last updated at Posted at 2025-06-09

はじめに

プログラミング言語の設計において「シンプルさ」は永遠のテーマです。新しい機能を追加すれば便利になるが、同時に複雑さも増します。この矛盾にRustはどう向き合っているのでしょうか?

今回は、Chad Nauseam氏による記事「Keep Rust Simple」を中心に紹介します。

Rustが持たない10の機能

Rustには、多くの言語が「便利」とする以下の機能がありません:

  1. 名前付き引数(Named arguments)
  2. デフォルト引数(Default arguments)
  3. 三項演算子(Ternary operator)
  4. null
  5. 例外(Exceptions)
  6. 関数のオーバーロード(Function overloading)
  7. 継承(Inheritance)
  8. コンストラクタ(C++的な意味での)
  9. 可変長引数関数(Variadic functions)
  10. 暗黙的な型変換(Implicit type conversions)

これらの機能がなくても、実際には何でもできます。これらは単なる「便利機能」であり、これらの便利機能がないことで言語がよりシンプルになります。学習しやすく、使いやすくなるのです。

「便利さのための複雑さ」vs「パワーのための複雑さ」

しかし、Rustが完全にシンプルかというと、そうではありません。例えば文字列型を見てみましょう:

  • &str:「文字列参照」
  • String:「所有された文字列」

もっと易しい言語から来た人には複雑に見えるかもしれません。なぜすべてをStringにしないのでしょうか?

これが 「便利さのために追加された複雑さではなく、パワーのために交換された複雑さ」 だと主張しています。

fn get_first_word(s: &str) -> &str {
    s.split_whitespace().next().unwrap_or("")
}

&strがあることで、「文字列の一部」への参照を、不要なコピーを作ることなく取得できます。これは実用的なパワーを提供する複雑さなのです。

静的解析によるシンプルさの実現

Rustのシンプルさの真価は、静的解析による間違いの防止にあります。以下のPythonコードを見てください:

# Python - 間違いを見つけるのが困難
x = [2, 1, 4]
x = x.sort()  # これはNoneを返すため、xはNoneになってしまう
print(x)

同じことをRustで書くとどうなるでしょうか:

fn test() {
    let x = vec![2,1,3];
    let x = x.sort();
    // error: cannot borrow `x` as mutable, as it is not declared as mutable
    println!("{x:?}")
}

さらに、変数を可変にしても:

fn test() {
    let mut x = vec![2,1,3];
    let x = x.sort();
    println!("{x:?}")
}

Rustは正確に何が間違っているかを教えてくれます:

warning: this let-binding has unit value
 --> src/lib.rs:3:5
  |
3 |     let x = x.sort();
  |     ^^^^^^^^^^^^^^^^^
help: omit the `let` binding and replace variable usages with `()`
  |
3 ~     x.sort();
4 ~     println!("{():?}")

間違いを検出して説明してくれる強力な静的解析は、実は初心者にとって非常に便利なのです(多くの間違いを犯しがちな初心者にとって特に)。

表現式としてのif:三項演算子の代替

Rustには三項演算子がありませんが、実際には必要ありません。なぜならifが式だからです:

let result = if condition { value_a } else { value_b };

これは三項演算子(condition ? value_a : value_b)と同じことができますが、新しい概念を言語に追加する必要がありません。

「機能の追加」より「制限の解除」

記事はRustの「シンプルな」側面を紹介していますが、Rustは比較的新しい言語で、次々に新たな機能が追加されています。ではシンプルさが失われつつあるかというとそうではありません。

十分に成熟した現代の言語設計では、「機能を追加する」よりも「制限を解除する」ことのほうが重要です:

  • 新しく覚えることを追加する

ではなく

  • 覚えることを減らす

ような言語変更です。

例えば:

  • traitsでasyncが使えるようになった
  • 借用チェッカーがPoloniusによってより寛容になる

これらは「新機能」ですが、学習者にとっては「当然できるはず」と感じられ、学習コストを下げることにつながります。

まとめ

「Keep Rust Simple」:

  1. 本当に必要な複雑さと、単なる便利さのための複雑さを区別すること
  2. 「機能の追加」よりも「制限の解除」を重視すること
  3. 静的解析によって間違いを早期発見すること

「シンプル」は目的ではなく、より良いプログラムを書くための手段なのです。

参考リンク

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?