前回の続き
関数
// u32型の値を返す関数
// u32型は符号なし32ビット整数型
fn greeting() -> u32 {
println!("Hello, from WebAssembly!");
42
}
// ユニット型を返す関数
// ユニット型は意味を持たない値を表す型
// 返り値がない場合に使われる
// 省略可能
fn greeting2() -> () {
println!("Hello, from WebAssembly!");
}
構造体
struct HelloWorld {
count: u32,
}
fn say(hello_world: HelloWorld) {
println!("カウンター: {}", hello_world.count);
}
fn new_hello_world(count: u32) -> HelloWorld {
HelloWorld { count }
}
所有権
let hello_world = new_hello_world(42);
say(hello_world);
// エラーが発生する
// 所有権が移動しているため
// say(hello_world);
error[E0382]: use of moved value: `hello_world`
--> src/main.rs:10:7
|
8 | let hello_world = new_hello_world(42);
| ----------- move occurs because `hello_world` has type `HelloWorld`, which does not implement the `Copy` trait
9 | say(hello_world);
| ----------- value moved here
10 | say(hello_world);
| ^^^^^^^^^^^ value used here after move
|
note: consider changing this parameter type in function `say` to borrow instead if owning the value isn't necessary
--> src/main.rs:32:21
|
32 | fn say(hello_world: HelloWorld) {
| --- ^^^^^^^^^^ this parameter takes ownership of the value
| |
| in this function
note: if `HelloWorld` implemented `Clone`, you could clone the value
--> src/main.rs:28:1
|
9 | say(hello_world);
| ----------- you could clone this value
...
28 | struct HelloWorld {
| ^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
For more information about this error, try `rustc --explain E0382`.
error: could not compile `hello-rust` (bin "hello-rust") due to 1 previous error
owner から所有権がanother_ownerに移動する。つまり参照する値が存在しない状態になる。参照する値が存在しないにも関わらず値を参照しようとするためビルドエラーになる
let owner = new_hello_world(43);
let another_owner = owner;
say(owner);
HelloWorldを返すように修正
let owner = new_hello_world(43);
let owner = say_and_return(owner);
say_and_return(owner);
fn say_and_return(hello_world: HelloWorld) -> HelloWorld {
println!("カウンター: {}", hello_world.count);
hello_world
}
借用
所有権の移動をしたくない場合に利用する
let hello_world = new_hello_world(0);
let borrowed = &hello_world;
say2(borrowed);
fn say2(hello_world: &HelloWorld) {
println!("カウンター: {}", hello_world.count);
}