関数の引数宣言における、無印とmut
と&mut
と&
の意味と使いどころをまとめる。
無印
所有権が関数に移動する。以上。
fn main() {
let s = String::from("hello");
takes_ownership(s);
}
fn takes_ownership(some_string: String) {
println!("{}", some_string);
}
&
所有権は移動しない。Readだけ可能、なはず。
fn main() {
let s = String::from("hello");
let len = calculate_length(&s);
}
fn calculate_length(s: &String) -> usize {
s.len()
}
&mut
所有権が一時的に移動する。Write可能。
fn main() {
let mut s = String::from("hello");
change(&mut s);
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
mut
所有権が関数に移動する。無印との違いは関数内で引数がmut
として扱えること。
fn main() {
let listener = TcpListener::bind("127.0.0.1:8090").unwrap();
for stream in listener.incoming() {
let stream = stream.unwrap();
handle_connection(stream);
}
}
fn handle_connection(mut stream: TcpStream) {
let buf_reader = BufReader::new(&mut stream);
let http_request: Vec<_> = buf_reader
.lines()
.map(|result| result.unwrap())
.take_while(|line| !line.is_empty())
.collect();
println!("Request: {:#?}", http_request);
}
ここでfn handle_connection(mut stream: TcpStream)
の宣言をfn handle_connection(stream: TcpStream)
と変えると
$ cargo run
Compiling todo-rust v0.1.0 (/home/coder/todo-rust)
error[E0596]: cannot borrow `stream` as mutable, as it is not declared as mutable
--> src/main.rs:17:37
|
17 | let buf_reader = BufReader::new(&mut stream);
| ^^^^^^^^^^^ cannot borrow as mutable
|
help: consider changing this to be mutable
|
16 | fn handle_connection(mut stream: TcpStream) {
| +++
For more information about this error, try `rustc --explain E0596`.
error: could not compile `todo-rust` due to previous error
下記のようにlet mut stream = stream;
と、関数内でmut
として再宣言すると問題なく進む。
fn handle_connection(stream: TcpStream) {
let mut stream = stream;
let buf_reader = BufReader::new(&mut stream);
let http_request: Vec<_> = buf_reader
.lines()
.map(|result| result.unwrap())
.take_while(|line| !line.is_empty())
.collect();
println!("Request: {:#?}", http_request);
}
やってることは同じだと思われる。