ここを見て0からrustを勉強し始めた

https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/README.html
予備知識として、ワイC言語10年くらいやってて、ここ5年くらいはphp、pythonあたりをメインに触っとる程度を前提に書くンゴ。

インストールまで完全に理解した

割愛。
アホでもできる。

3.1. 数当てゲーム 完全に理解した

https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/guessing-game.html
↑こいつを見ていく

まずはプロジェクト作成、余裕、完全に理解した。

$ cargo new guessing_game --bin
$ cd guessing_game

外部クレート(パッケージ)を使用するのでCargo.tomlに追記

dependencies に randを追記、バージョンを現時点最新のを指定してみた。

[dependencies]

rand="0.4.6"

まずはソースの完成形、完全に理解したわ

extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    loop {
        println!("Please input your guess.");

        let mut guess = String::new();

        io::stdin().read_line(&mut guess)
            .expect("Failed to read line");

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

        println!("You guessed: {}", guess);

        match guess.cmp(&secret_number) {
            Ordering::Less    => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal   => {
                println!("You win!");
                break;
            }
        }
    }
}

ソース、ちょい掘り下げて

外部クレートのrandを使えるようにする明示的宣言、Cの外部関数extern宣言と同じような意味合い。
externしなくても use rand::Rng があればコンパイル通る

extern crate rand;

!が付いてるのは関数じゃなくマクロ

println!("Please input your guess.");

let 変数束縛を作る。他言語と一番の違うのがこの辺、ここさえ乗り切ればrust完全に理解できると思う。
変数束縛とか言って、変数名に対して値を束縛する、とか言って所有権という概念が生まれる。
rustの言語の仕様として「Rustは与えられたリソースに対する束縛が 1つだけ あるということを保証する」

んで、変数束縛定義にmutを付けない場合、イミュータブルとか言って書き換え不可の定数になる。
gen_range(1, 101);は数値型を返され、secret_numberという変数に1~100の乱数が入る、
secret_numberがある数値を束縛する、secret_numberがこの乱数のリソースの所有権を持つ。

let secret_number = rand::thread_rng().gen_range(1, 101);

書き換え可能な変数作成は明示的にmutを付ける必要がある、ミュータブルとか言うやつ。
let mut guess = String::new(); の場合、guessという名前の変数にはString型のデータが入る。
String型にはポインタが含まれる、ので、この guess を別の変数に代入した場合、
guessとその別の変数はそれぞれ、同じアドレスを参照するポインタを持つことになるので、
同じリソースに対する束縛が同時に二つ存在することになる。
「Rustは与えられたリソースに対する束縛が 1つだけ あるということを保証する」ので、guess所有権が別の変数に渡され、
guess に対するアクセスができなくなる。
let aaa = guess;
println!(“{}”, guess); <= ここでコンパイルエラーになる。

let mut guess = String::new();

stdinのread_lineで入力された文字列をguessに入れる。この辺は直感的に理解できるが、
read_line(&mut guess) 見慣れない。read_lineの引数が&mut参照型なのでこうやって渡す必要がある。
ミュータブルの参照型で、参照先で変数を書き換え可能になる。
かつ、&を付けて参照で渡していると、所有権を渡すのではなく、借用することになる、スコープから外れると所有権が自動で元の束縛に戻る。
なので、read_line(&mut guess) でguessが束縛しているリソースをread_lineに借用、read_lineから抜けると自動的にguessに所有権が戻る。
上記④のようなコンパイルエラーが起きなくなる。

io::stdin().read_line(&mut guess)
            .expect("Failed to read line");

長くなったので一旦区切り

続く。

bannerAds