Tôi vừa mới viết một chương trình Rust nhỏ tính số Fibonacci và ghi nhớ phép tính. Nó hoạt động, nhưng tôi là một chút bối rối về lý do tại sao, đặc biệt là các cuộc gọi đệ quy. (Nó cũng có thể không phải là thành ngữ.)Tại sao tôi không cần phải cho vay một cách rõ ràng, một biến có thể thay đổi được?
Dưới đây là các chương trình:
use std::collections::HashMap;
fn main() {
let n = 42; // hardcoded for simplicity
let mut cache = HashMap::new();
let answer = fib(n, &mut cache);
println!("fib of {} is {}", n, answer);
}
fn fib(n: i32, cache: &mut HashMap<i32,i32>) -> i32 {
if cache.contains_key(&n) {
return cache[&n];
} else {
if n < 1 { panic!("must be >= 1") }
let answer = if n == 1 {
0
} else if n == 2 {
1
} else {
fib(n - 1, cache) + fib(n - 2, cache)
};
cache.insert(n, answer);
answer
}
}
Đây là cách tôi hiểu những gì đang xảy ra:
- Trong
main
,let mut cache
có nghĩa là "Tôi muốn có thể để thay đổi hashmap này (hoặc gán lại biến) "#:. - Khi
main
gọifib
, thẻ này chuyển số&mut cache
để nói "Tôi đang cho bạn mượn điều này và bạn được phép biến đổi nó". - Trong chữ ký của
fib
,cache: &mut Hashmap
có nghĩa là "Tôi hy vọng sẽ được vay một HashMap có thể thay đổi - để mượn nó với sự cho phép để đột biến"
(Xin vui lòng sửa cho tôi nếu tôi sai.)
Nhưng khi fib
đệ quy, gọi số fib(n -1, cache)
, tôi không cần sử dụng fib(n -1, &mut cache)
và tôi gặp lỗi nếu tôi làm: "không thể mượn biến cục bộ bất biến cache
là có thể thay đổi". Huh? Nó không phải là một biến địa phương bất biến, đó là một khoản vay có thể thay đổi - đúng không?
Nếu tôi cố gắng fib(n - 1, &cache)
, tôi nhận được một lỗi hơi khác nhau:
error: mismatched types:
expected `&mut std::collections::hash::map::HashMap<i32, i32>`,
found `&&mut std::collections::hash::map::HashMap<i32, i32>`
Mà có vẻ như nó đang nói "Tôi mong đợi một tài liệu tham khảo có thể thay đổi và có một tham chiếu đến một tài liệu tham khảo có thể thay đổi".
Tôi biết rằng fib
là cho vay trong cuộc gọi đệ quy vì nếu đã từ bỏ quyền sở hữu, nó không thể gọi cache.insert
sau đó. Và tôi biết rằng đây không phải là trường hợp đặc biệt cho đệ quy, bởi vì nếu tôi xác định fib2
để gần giống với fib
, tôi có thể yêu cầu họ tái xử lý qua nhau và nó hoạt động tốt.
Tại sao tôi không cần phải cho vay một cách rõ ràng, biến có thể biến đổi?
Bạn có thể chuyển quyền sở hữu và có chức năng trả về một bộ dữ liệu có câu trả lời và bộ nhớ cache: [PlayPen] (http://is.gd/tUadZ0) –