hiro99ma blog

Something technical

rust: Rustがんばろう 10日目

2025/04/08

はじめに

そうだ、私はそういえば Rust の勉強をしていたのだった。

そんな記憶すらもう過去のものだ。

前回何をしていたか

8章のまとめにある課題をやっていたようだ。

8章はコレクション関係で、Vec<T>StringHashMap<K,V> の紹介が行われている。

String

未だにピンと来てないのは String 関係だ。
そろそろ “The Rust Programming Language” 以外の資料も見た方がよいのかもしれないが、 もうしばらくはこのドキュメントでの見方で学習し、その後で他の視点を参考にしていこう。

use std::collections::HashMap;

fn main() {
    let mut scores: HashMap<String, i32> = HashMap::new();
    scores.insert(String::from("Blue"), 10);
    for v in scores {
        println!("{} - {}", v.0, v.1);
    }
}

たとえば HashMap<&str, i32> にすると .as_str() を付けたりして型だけあわせてもダメだ。

    let mut scores: HashMap<&str, i32> = HashMap::new();
    scores.insert(String::from("Blue").as_str(), 10);

“temporary value dropped while borrowed” となるのはこういう流れだろうか。

  1. String::from() でインスタンスが作られる
  2. そのインスタンスのメソッド? .as_str() が呼ばれるが、HashMap<> の Key になるのは借用した &str だけ
  3. scores.insert() が終わると String::from() のインスタンスは不要なので解放したいが借用されているのでそうはいかない
  4. エラーじゃ

String::from()のインスタンスをあらかじめ作っておけばエラーにならない。
なのでここの原因は型がどうこうではなく所有権がらみということだ。
String::from().as_str() という書き方はどこであってもダメってことだね。

    let mut scores: HashMap<&str, i32> = HashMap::new();
    let v = String::from("Blue");
    scores.insert(v.as_str(), 10);

おなじ v を使い回してもエラーにならない。
まあ、値を上書きするわけじゃないしね。

    let v = String::from("Blue");
    scores.insert(v.as_str(), 10);
    let v = String::from("Yellow");
    scores.insert(v.as_str(), 50);

では vmut にして代入したら?とやってみたが、 mut じゃなくていいよね、ということだと思われる警告が表示される。
代入する箇所はエラーで、借用してるのにそんなことしたらいかんよ、というところか。

    let mut v = String::from("Blue");
    scores.insert(v.as_str(), 10);
    v = String::from("Yellow");

i32 などは mut にすると代入ができるようになるが、struct みたいなやつはメソッドを呼び出して中身に変更を及ぼすという意味になる気がする。

まだねー、そういうのが理屈で説明できないのだ。

ともかく、今回は最初の書き方が一番素直で楽ということになる。

use std::collections::HashMap;

fn main() {
    let mut scores: HashMap<String, i32> = HashMap::new();
    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Yellow"), 50);
    for (key, value) in scores {
        println!("{} - {}", key, value);
    }
}

C言語の気持ちだと、どうせヒープに割り当ててるんだろうから & を付けてアドレスだけでいいんじゃないのという気持ちになるのだ。
Rust の & なので違うとは分かっているのだが、インスタンスを直接引数に入れ込むことに抵抗があるのよねぇ。


 < Top page


コメント(Google Formへ飛びます)

GitHub

X/Twitter

Homepage