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
まとめ