見出し画像

Retro-gaming and so on

RE: プログラミング学習日記 2024/04/12〜

龍虎氏の記事についてのコメント。

まず最初にRustによるコードとC言語によるコードを並べてみよう。


両者とも見た目は確かに良く似ていると思う。
「見かけ」に関して言えば、確かにRustは「Cっぽく見せる」ようにしている。
ただし、細かいトコでは当然、色々と違いがあるんだ。

まずMain部分、なるほどFnって何だよw。

fnは予想通りfunction(関数)の事だ。ザックリ言っちゃえばRacketのdefine、Pythonのdefの類だと考えていい。あるいはJavaScriptのfunctionか。functionもどんどん縮めちゃってとうとう2文字だ(笑)。
いずれにせよ、関数定義用のキーワードだと考えていい。
そして実はこれがC言語にはないんだ。

この冒頭部分だけ、を比較すると、

// Rust
fn main() {
// C言語
int main(void) {

と確かに似てるが、Rustが「mainと言う関数を定義しますよ」と言ってるのに対し、C言語は単に「構文構造上」関数定義になる。じゃあintは?と言うのはこれは関数定義ではなく、その関数が返す値の型を意味してる(結果、mainは整数型を返す関数、って事になる)。
Rustの場合、上のmain関数は返り値がないんで、どっちかっつーと手続き(プロシージャ)になってる。そして返り値がある場合、Cと違って、矢印を使った、一般的にアノテーションと呼ばれる形式で、返り値の型を指定する。

// 返り値の型が32ビット幅の整数型の場合
fn five() -> i32 {
  5
}

この辺は、C言語系に見せかけておいて実は全く違うんで覚えておこう(※1)。

そして()をつけてからの{か〜

main関数も関数である以上引数リストが必要・・・なんだけど、Racketだと無引数関数はこんなんだしな(笑)。

(define (main) ...

そうね、Racketやってたらフツーの言語の「引数リスト」ってピンと来ねぇよなぁ(笑)。
そういや、OCamlでも引数ってカッコ伴わなかったわ(笑)。
こう考えてみると、龍虎氏っていわゆる「フツーのプログラミング言語」ってやった事ねぇんだよな(ヲイ)。

なお、C言語の場合、仕様上、無引数関数の場合、定義時の引数リストのカッコ内にvoidを入れるお約束になっている。「何も置かない」ってのは仕様上非推奨なんだ。
(Rustみたいに空カッコで書く人がいまだ多いけど間違っている)

Println!は;してから}か〜

ここに注意!
ホントRustはC言語の「見た目」を良く真似してるんだけど、実はこのセミコロン(;)の意味がCとRustじゃ全然違うんだ。
Cだと「式の終わり」を意味してて、そこが無いと文法エラーになる。
一方、Rustは、実は一般的な明示的構文であるreturnが無い言語なんだ。
Rustはその代わり、式の終わりにセミコロンを置けばその返り値を無視し、セミコロンがない式が関数全体(あるいは構文)の返り値になる。
上で例に挙げたコードをもう一回見てみよう。

// 返り値の型が32ビット幅の整数型の場合
fn five() -> i32 {
  5
}

この本体の式である5の後ろにはセミコロンが置いてない。従って、ここでは5が返り値になる、ってわけだ。
件のFizzBuzzのコードでprintln!が形成する式にセミコロンが必要なのは、そこのmain関数が事実上プロシージャで返り値を必要としてないから、なんだ。

Elifじゃなくて以降は全部Elseで良いんだね、合理的。

この辺ちとPython混ざった判断だったかも(笑)。
と言うか、elifなんてヘンなキーワードってPythonくらいしかなくない(笑)?
多分。

Println!の変数挿入は"{}", nか〜

Pythonでも3.x以降すっかりお馴染みになったプレースホルダー({})だ。
多分ルーツはC#かね?非常に便利でエエもんです(笑)。
(もっとも、Lispではformat~aがある場合が多いけど)

※1: Racketでも引数へ与える型、返り値の型、が分かってる場合、define/contractでアノテーションを使って静的型付け言語のように書く事が出来る。
また、Pythonで最近、静的言語ユーザーに応える為、関数アノテーションと言う機能を提供している。

  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「RE: プログラミング学習日記」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事