Mobility Technologies Co., Ltd.
俺の
let p = PathBuf::from(“/test”).into_os_string().to_str();
はなぜコンパイルエラーか
Shunsuke Nakamura
2020/10/29 MoT.rs #2
Mobility Technologies Co., Ltd.
タイトルを通してRustにおける配列/ベクタとスライスの違いを理解する



タイトルの疑問に答えられるようになる
2
5分後の目標
Mobility Technologies Co., Ltd.3
PathBufオブジェクトを文字列*にしようとするとコンパイルエラー
let path = PathBuf::from("/path/to/file");

let path_str = path.into_os_string().to_str();

let path = PathBuf::from("/path/to/file");

let path_str = path.into_os_string().to_str();

creates a temporary which is freed while still in use

cargo check(ビルドせずにコンパイルエラーを検知する)
*正確にはOption<&str>
Mobility Technologies Co., Ltd.4
PathBufオブジェクトを文字列にしようとするとコンパイルエラー
let path = PathBuf::from("/path/to/file");

let path_str = path.into_os_string().to_str();

let path = PathBuf::from("/path/to/file");

let path_str = path.into_os_string().to_str();

creates a temporary which is freed while still in use

cargo check(ビルドせずにコンパイルエラーを検知する)
配列とスライスを抑えれば簡単!

Mobility Technologies Co., Ltd.
Rustには実体である配列/ベクタと、それの参照であるスライスが存在する





5
Rustにおける配列とスライス
let array: &[i32;3] = [1, 2, 3]; // 要素数3のi32を持つ配列

let slice_of_array: &[i32] = &array[1..2]; // 要素がi32のスライス

let ref_of_array: &[i32; 3] = &array; // これは要素数3のi32を持つ配列の参照

1 2 3stack
reference of vector
pointer
length
slice of vector
array
pointer
Mobility Technologies Co., Ltd.
ベクタは配列よりちょっとメタ情報が増えるが同じ



6
Rustにおけるベクタとスライス
let vector: Vec<i32> = vec![1, 2, 3]; // i32を持つベクタ

let slice_of_vector: &[i32] = &vector[1..2]; // 要素がi32のスライス

let ref_of_vector: &Vec<i32> = &vector; // これはi32を持つベクタの参照

1 2 3heap
reference of vector
pointer
pointer
length
slice of vector
size capvector
pointer
Mobility Technologies Co., Ltd.
String = utf-8のベクタ str = Stringに対するスライス



7
Rustにおける文字列と文字列のスライス
let string: String = String::from("MoT"); // “MoT”を持つStringオブジェクト

let slice_of_string: &str = &string[1..2]; // Stringオブジェクトに対するスライス

let ref_of_string: &String = &string; // これはStringオブジェクトに対する参照

M o Theap
reference of String
pointer
pointer
length
&str = Slice of string
size capString
pointer
Mobility Technologies Co., Ltd.8
何が起きていたのか
let path = PathBuf::from("/path/to/file");

let path_str = path.into_os_string().to_str();

creates a temporary which is freed while still in use

path PathBufオブジェクトのmove
.into_os_string() OsStringオブジェクト作成(Stringオブジェクトのようなもの)
.to_str() OsStringオブジェクトに対するスライス作成
; OsStringオブジェクトの破棄(;で一時オブジェクトが破棄される)

スライスをpath_strにバインド ← dangling pointer

Mobility Technologies Co., Ltd.9
解決策: 一時オブジェクトをlet bindしてライフタイムを伸ばす
let path = PathBuf::from("/path/to/file");

let path_os_string = path.into_os_string();

let path_str = path_os_string.to_str();

Mobility Technologies Co., Ltd.
Rustでは配列・ベクタに対し、そのポインタと長さを持つスライスが存在する





タイトルの答えは、

creates a temporary which is freed while still in use とあるように

文末で破棄される一時的な実体に対してスライスを持とうとしていることが原因





10
まとめ
文章·画像等の内容の無断転載及び複製等の行為はご遠慮ください。
Mobility Technologies Co., Ltd.
11

俺の let p = PathBuf::from("/test").into_os_string().to_str();はなぜコンパイルエラーか

  • 1.
    Mobility Technologies Co.,Ltd. 俺の let p = PathBuf::from(“/test”).into_os_string().to_str(); はなぜコンパイルエラーか Shunsuke Nakamura 2020/10/29 MoT.rs #2
  • 2.
    Mobility Technologies Co.,Ltd. タイトルを通してRustにおける配列/ベクタとスライスの違いを理解する
 
 タイトルの疑問に答えられるようになる 2 5分後の目標
  • 3.
    Mobility Technologies Co.,Ltd.3 PathBufオブジェクトを文字列*にしようとするとコンパイルエラー let path = PathBuf::from("/path/to/file");
 let path_str = path.into_os_string().to_str();
 let path = PathBuf::from("/path/to/file");
 let path_str = path.into_os_string().to_str();
 creates a temporary which is freed while still in use
 cargo check(ビルドせずにコンパイルエラーを検知する) *正確にはOption<&str>
  • 4.
    Mobility Technologies Co.,Ltd.4 PathBufオブジェクトを文字列にしようとするとコンパイルエラー let path = PathBuf::from("/path/to/file");
 let path_str = path.into_os_string().to_str();
 let path = PathBuf::from("/path/to/file");
 let path_str = path.into_os_string().to_str();
 creates a temporary which is freed while still in use
 cargo check(ビルドせずにコンパイルエラーを検知する) 配列とスライスを抑えれば簡単!

  • 5.
    Mobility Technologies Co.,Ltd. Rustには実体である配列/ベクタと、それの参照であるスライスが存在する
 
 
 5 Rustにおける配列とスライス let array: &[i32;3] = [1, 2, 3]; // 要素数3のi32を持つ配列
 let slice_of_array: &[i32] = &array[1..2]; // 要素がi32のスライス
 let ref_of_array: &[i32; 3] = &array; // これは要素数3のi32を持つ配列の参照
 1 2 3stack reference of vector pointer length slice of vector array pointer
  • 6.
    Mobility Technologies Co.,Ltd. ベクタは配列よりちょっとメタ情報が増えるが同じ
 
 6 Rustにおけるベクタとスライス let vector: Vec<i32> = vec![1, 2, 3]; // i32を持つベクタ
 let slice_of_vector: &[i32] = &vector[1..2]; // 要素がi32のスライス
 let ref_of_vector: &Vec<i32> = &vector; // これはi32を持つベクタの参照
 1 2 3heap reference of vector pointer pointer length slice of vector size capvector pointer
  • 7.
    Mobility Technologies Co.,Ltd. String = utf-8のベクタ str = Stringに対するスライス
 
 7 Rustにおける文字列と文字列のスライス let string: String = String::from("MoT"); // “MoT”を持つStringオブジェクト
 let slice_of_string: &str = &string[1..2]; // Stringオブジェクトに対するスライス
 let ref_of_string: &String = &string; // これはStringオブジェクトに対する参照
 M o Theap reference of String pointer pointer length &str = Slice of string size capString pointer
  • 8.
    Mobility Technologies Co.,Ltd.8 何が起きていたのか let path = PathBuf::from("/path/to/file");
 let path_str = path.into_os_string().to_str();
 creates a temporary which is freed while still in use
 path PathBufオブジェクトのmove .into_os_string() OsStringオブジェクト作成(Stringオブジェクトのようなもの) .to_str() OsStringオブジェクトに対するスライス作成 ; OsStringオブジェクトの破棄(;で一時オブジェクトが破棄される)
 スライスをpath_strにバインド ← dangling pointer

  • 9.
    Mobility Technologies Co.,Ltd.9 解決策: 一時オブジェクトをlet bindしてライフタイムを伸ばす let path = PathBuf::from("/path/to/file");
 let path_os_string = path.into_os_string();
 let path_str = path_os_string.to_str();

  • 10.
    Mobility Technologies Co.,Ltd. Rustでは配列・ベクタに対し、そのポインタと長さを持つスライスが存在する
 
 
 タイトルの答えは、
 creates a temporary which is freed while still in use とあるように
 文末で破棄される一時的な実体に対してスライスを持とうとしていることが原因
 
 
 10 まとめ
  • 11.