Rust プログラミング言語学習ガイドライン
はじめに#
最も重要なことは、この「Rust プログラミング言語学習ガイドライン」という名前が少し大げさに聞こえることです。しかしご安心ください、この名前を付けた唯一の理由は、見栄えを良くするためです。これにより、この小冊子を持って公共の場に行ったときに(おそらく)高い注目を集め、あなたの学習意欲を高めることができるかもしれません。
Rust は 2015 年に誕生し、今から 9 年が経過しました。すでに一定の歴史を持つプログラミング言語です。もしインターネットで Rust に関する情報を検索すると、さまざまな意見が見つかります。Rust は難しい言語である以外はすべて良い言語だとコメントする人もいます。確かに、Rust は難しい以外のすべてのプログラミング言語の優れた特性を持っていると評価されることがあります。そのメモリ安全性、並行安全性、実行効率などは比類のないレベルに達しています。また、高効率または現代的な Cargo パッケージマネージャーや、C 標準に準拠した一連のコンパイラツールチェーン(Rust の公式コンパイラは現在も gcc GNU C コンパイラに基づいています)と組み合わせることで、開発からデバッグまで非常に簡単です。さらに、オープンソースコミュニティから生まれ、オープンソースコミュニティを対象とした言語であるため、これらの特性はバージョン管理システム(Rust Cargo ではデフォルトで Git)の大規模な共同開発に非常に適しています。Rust は 9 年の発展を経て、比較的新しい言語であるにもかかわらず、すでに多くの認知を得ています。その中には名だたる企業や有名なオープンソース開発者(例えば、Linux カーネル開発者の Linus Torvalds は、カーネルに Rust を追加して部分的に C を置き換える準備を進めています)も含まれています。これらの用語が理解できないかもしれませんが、安心してください。この段落の主旨は、Rust は間違いなく良い言語であるということです。
「でも Rust は難しいです。ネットで勧められているように、まず C を学んでから Rust を学ぶべきではないですか?」確かに、もし C 言語や C++ に触れたことがあるなら、Rust を学ぶ際はずっと楽になるでしょうし、この小冊子の第一章(「コンピュータを理解する」)は飛ばしても良いでしょう。しかし、Rust を学ぶために C/C++ を学ぶべきだという考えがあるのは、Rust の多くの特性が C/C++ や他のいくつかのコンパイラ型の、やや低レベルな言語の欠点を解決するために提案されたからです。そして Rust が難しいと言われるのもそのためです —— もし低レベルプログラミングに触れたことがない人が Rust を学ぶと、多くの特性が完全に不要で無意味に感じられるでしょう —— 実際、プログラミングに触れたことがないか、トップレベルのプログラミング(JavaScript、Python、さらには Scratch)しか経験していない場合、コンピュータの理解が完全に不足しています。この小冊子は、読者に「Hello World」をどうやって印刷するかを教えるのではなく(実際、読者は後で「Hello World」を書く必要がないことを知るでしょう。なぜなら、Rust の新しいプロジェクトのデフォルトテンプレートは「Hello World」だからです)、約 1000 字の図文を交えた形式で、コンピュータの動作原理の最も重要な部分を簡潔に伝えます。そして、後の章でも常に原理からアプローチすることに注意します。こうすることで、他のプログラミング言語を学んだことがない人でも、コンピュータについての理解を深めることで、Rust の卓越した設計を体感し、より良い学習効果を得ることができます。
「なぜ私が聞いたこともないこの言語を学ぶ必要があるのか?」という疑問もあるかもしれません。確かに、Rust は難易度が高く、適用範囲が比較的狭いため、多くの初心者に避けられ、Python や JavaScript のような言語で十分に日常のニーズを満たせると考えられています。彼らの言い分は間違っていませんが、JavaScript はワールドワイドウェブ向けのプログラミング言語であり、その最大の特徴は非常に学びやすいことです。もし Rust を学んだ後に JavaScript を学ぶと、ほとんど学ぶ必要がないでしょう。ここで、これらのスクリプト言語を貶める意図はありませんが、事実として、これらのより高級な(私たちが言った高級と低級はハードウェアとの距離に関してです)言語は誰でも学べ、誰でも習得でき、また高度に新しい技術に依存し、フレームワークに依存しています。彼らが提供できるのは、雇用市場やオープンソースの世界での地位の幅と高さが非常に限られています。また、現代のコンピュータの動作原理を理解せず、ビジネスロジック(JavaScript の焦点)を処理するだけでは、低レベルの問題が発生したときに自分でトラブルシューティングすることができず、他の人に頼ることになります。低レベルの問題は、言語が高級だからといって存在しないわけではありません。逆に、低レベルの業務は必ず誰かが処理しなければならず、それがインタープリタやインタープリタ開発者の仕事です。彼らこそが業界の中心となるのです。ポインタのような低レベルの特性は、インタープリタが保姆のようにそれらを封装し、管理しているだけです。効率や柔軟性において、実際に自分で手を動かすことには到底及びません。Rust を学ぶことで、コンピュータについてより理性的で正確な理解を得ることができれば、日常生活や生産の中で遭遇する多くの問題を明確な頭で解決できるようになり、他の言語を学ぶことも容易になります。そして、もしかしたら、低レベルの業務を処理する達人になり、業界のリーダーになることもできるかもしれません。
さらに、Rust は多くの人が言うように「ドライバやオペレーティングシステムを書くためのもの」ではありません。逆に、現在多くの企業が Rust を生産環境で使用し、ネットワークサーバーや他のデジタルインフラを運用しています。なぜなら、Rust には二つの重要な特性があるからです:ゼロコスト抽象による高性能、現代的なメモリと並行管理による実行安全性。しかし、コンピュータの基本原理を理解せず、前述のようにスクリプト言語のインタープリタを保姆のように扱っていると、これらのコンピュータ時代の安定性に関わる要素を永遠に理解することはできません。
コンピュータを理解する#
この章に必要な前提知識:基本的な生活経験です。もし理解できない用語に出会った場合、文中に説明がない場合はそのまま飛ばしてください。これらの用語はこの章やこの小冊子を理解する上で(当面)必要ではありません。
現代のコンピュータは非常に複雑な装置に見えます;もちろん、実際にそうです。普通のノートパソコンの構造は、人類がこれまでに製造した中で最も集積度の高い構造でしょう。しかし、いずれにせよ、コンピュータは機械であり、完全に人間が設計したものです。科学者たちは、コンピュータを人間の脳と同じくらい複雑に設計し、人間の脳と同じように複雑で巧妙な機能を実現しようと考えたことはありませんでした。20 世紀中頃には、あるグループの科学者が試みましたが、当時の(そして現在の)生理学の理解の限界により、人間の脳の最も概括的な原理図さえも明確にすることが難しかったのです。そこで、フォン・ノイマンをはじめとする科学者たちは、超シンプルな計算体系アーキテクチャを設計する道を選びました。結局、汎用コンピュータを作る目的を達成できればよく、人間の脳レベルの複雑さを追求する必要はありませんでした。こうして「超シンプル」なフォン・ノイマンアーキテクチャが誕生しました。
まあ、そんなに「簡単」ではないかもしれません。しかし、概要は非常に明確です。フォン・ノイマンアーキテクチャは、過去、現在、そして未来のすべての汎用コンピュータの基本アーキテクチャを定義しています:演算器(CPU)、入出力(I/O Bridge)、メモリ(Memory)。簡単に言うと、演算器は計算の部分、入出力はそのままの意味、そして(メモリ)は物を保存する場所です。絶対に間違えないでください、メモリは RAM であり、一般的に言われる「メモリモジュール」です。混同されがちなのはハードディスクです;ハードディスクは入出力デバイスの一種です!メモリは揮発性ストレージまたは RAM とも呼ばれ、** 電源が切れると中のすべてのものが消去されます(そうでなければ、なぜ揮発性ストレージと呼ばれるのでしょうか)** が、読み書きの速度は非常に速く、サイズは一般的に非常に小さく、通常(ほとんどの場合)ファイルを保存するためには使用されません。ハードディスクは、上の図の「Bus」(一般的に言われるバス)の部分に接続されている入出力デバイスで、入出力データを保存するためのものです。メモリとハードディスクはどちらも物を保存できますが、最大の違いは、ハードディスクは CPU とメモリという「工場」の出力結果を受け取り、入力材料を提供するためのデバイスであり、工場の倉庫のようなものです。メモリはこの工場の中の机や椅子で、作業者やさまざまな道具に一時的な保管スペースを提供し、加工待ちの材料に加工のための作業台を提供します。混乱を避けるために、この小冊子ではすべての「メモリ」を「主記憶装置」と表現し、同時に「実行データ」を揮発性ストレージ内に存在するデータや命令を指すために使用しますので、読者は注意してください。また、工場の比喩はこの小冊子全体にわたって使用されますので、後でその理由がわかります。
CPU 内部にもストレージ機能を持つコンポーネントがあります。全宇宙に適用される機械原理は、ストレージデバイスの一つの特性を決定します:容量が小さいほど、速度が速い(技術原理の違いを無視した文脈で)。したがって、CPU 内部にあるこれらのストレージコンポーネントの容量は非常に小さく、最大でも数 MB を超えることはありません(もちろん、このサイズは現代の CPU が提供するものです;いくつかの古い教科書では、CPU 内のストレージコンポーネントのサイズは数バイトしかないと言われることがあります)。工場の比喩を使うと、主記憶装置が加工台で、加工待ちの材料を置く場所だとすると、これらの CPU 内部のストレージコンポーネントは工具箱のようなもので、非常に短い時間で小さな部品を保管し、非常に「使いやすい」場所に置かれ、すぐに取り出せるようになっています。加工台に物を置く(主記憶装置から読み書きする)のに必要な時間は、工具箱から部品を取り出す(CPU 内部ストレージから読み書きする)のに必要な時間よりも数十倍長くなりますが、前者はすでに半ミリ秒未満です。
これらの CPU 内部のストレージコンポーネントには、それぞれの名前があります。一部は「キャッシュ」(cache)と呼ばれ、一部は「レジスタ」(register)と呼ばれますが、読者はそれらを理解する必要はありません。一部の教科書では、プログラミングの際にプログラムがさまざまなデータをキャッシュ、レジスタ、または主記憶装置に保存するよう要求できると言われることがありますが —— そのような要求は信じたり実践したりしないでください。現代のプログラミング言語と現代のオペレーティングシステムは、安全性と安定性の観点から、プログラムのこのような要求を無視します。Rust は、コンパイル時にどのプログラムにも実行時データの保存位置を選択する権利を与えません。したがって、CPU 内部のストレージコンポーネントについては、これ以上紹介したり理解したりすることはありません。読者はそれが存在することを知っていれば十分です。プログラムにとって、彼らが見ることができる部分は、単純に計算を提供する CPU、単純に実行データの保存を提供する主記憶装置、そして他の I/O デバイス(ハードディスク、プリンター、カメラ、マイク、スピーカーなど)だけです。ちょうど工場のマネージャー(オペレーティングシステム)が作業者に各物をどこに置くべきかを指示するように、彼らが自由に置くことはありません。
CPU が計算を提供する原理は非常に複雑です。しかし、皆さんは基本的な四則演算や他の一連の高度な関数を実行できることを知っています;これらは数学やデジタル回路設計の範疇です。私たちはハードウェアに近づく必要がありますが、そこまで近づく必要はありません。また、著者の能力には限界があるため、この部分についてはこれ以上詳しく述べません。
I/O ブリッジは、この記事では入出力または I/O ブリッジと呼ばれ、I/O バスと CPU および主記憶装置を接続します。これは工場の材料の入力口と製品の出力口のようなものです。I/O ブリッジがなければ、この工場の存在も無意味です。I/O バスは少し奇妙に聞こえるかもしれませんが、その英語名はすべてをうまく説明しています。「Bus」、バスです。確かに、I/O バスはバスのように、データをそれらの場所(これは多くの可能性があります。他の工場の出力である可能性もあれば、特定のデバイスである可能性もあります)から工場に運びます;またはその逆です。I/O という名前は非常に広く使われることもあります。結局、input /output の意味です(入力 / 出力)。すべての工場には進料口と出力口があります;したがって、各機械(プログラム)にも進料口と出力口があります。したがって、プログラミング中に I/O がユーザーの入力や画面に表示されることを表すために使用されているのを見ると、驚く必要はありません。
これで、私たちのコンピュータシステムの旅は終わりです。この部分の内容は詳細に説明すれば一冊の大作になることができます(「コンピュータシステムを深く理解する」をお勧めします。コンピュータシステムを深く理解したい場合は)、しかしプログラムを対象とした学習に関しては、これで十分です。
P.S. なぜコンピュータを工場に、プログラムを機械に例える比喩が非常に一般的であり、この記事でも使用されるのか?それは、現代のコンピュータの正式名称が実際には汎用コンピュータだからです。言い換えれば、孫悟空のように七十二変化できる(しかも同時に変化できる)さまざまな専用目的の機械に変化できるということです —— 実際には、汎用コンピュータが誕生する前や特定の分野で使用される前に存在していた専用コンピュータ(一般的には専用デバイス、IC(集積回路)などと呼ばれます)です。例えば、スイッチは典型的な専用コンピュータであり、プログラム可能ではなく、他の目的に使用することはできません;しかし、パーソナルコンピュータは汎用コンピュータであり、プログラミングや既存のプログラムをインストールすることで電話、電子メールの送受信機、スイッチ、ルーター、サーバーに変えることができます…… 汎用コンピュータ技術が成熟し、専用コンピュータのように毎回特別な集積回路を設計する必要がなくなり、さらに多くの機能を実現するために、ますます多くの専用コンピュータデバイスが汎用コンピュータに置き換えられています。例えば、IoT デバイスのネットワーク接続された温水器は、単一の回路基板の汎用コンピュータ(マイコン)によって制御されています;ある意味で、このようなデバイスはパーソナルコンピュータと本質的に同じです!このような比喩が合理的に成立するのは、それがある意味で汎用コンピュータ誕生前の世界を描写しているからです —— また、大多数の人々が知っていて本能的に受け入れられる世界でもあります。
次の章では、Rust を使って Hello World を書くことを学びます。(しかし、実際には簡単な文字列検索の小プログラムを書くことになります —— 心配しないでください、これは簡単にできます。)