雑なメモ書き

気楽にいきます

Rustのリテラル文字列はどういう扱いなのか?

参考

変な現象に遭遇する

  • まあ結果的に変じゃないんですけど
  • リテラルの文字列を扱うとエラーにならない
  • 所有権がmoveした物を使用したらこんぱいるできないんじゃないの?
fn main() {
    let s = "hello";
    let s2 = s;
    println!("{},{}",s,s2);
}
 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.19s
     Running `target/debug/hello`
hello,hello

想定していた動作

fn main() {
    let s = String::from("hello");
    let s2 = s;
    println!("{},{}",s,s2);
}
  • これですよこのエラーが出るのを期待していたんですよ
 cargo run
   Compiling hello v0.1.0 (/data)
error[E0382]: borrow of moved value: `s`
 --> src/main.rs:4:22
  |
2 |     let s = String::from("hello");
  |         - move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
3 |     let s2 = s;
  |              - value moved here
4 |     println!("{},{}",s,s2);
  |                      ^ value borrowed here after move

error: aborting due to previous error

For more information about this error, try `rustc --explain E0382`.
error: could not compile `hello`.

To learn more, run the command again with --verbose.

そもそもの理解

  • String型はCopyトレイトを実装していない為
  • 別の変数にバインディングをした場合
  • バインディング先の変数へ所有権を移動させる
  • 所有権が移動した変数を参照することはできない

いま起きてて困っていること

  • Stringとstrが同一の挙動をすると思っていたら
  • strの方は所有権が移動せずエラーにならない

そして気づいた

f:id:hiroyukim:20200209100010p:plain

前者の文字列

後者の文字列

つまりこういうこと