मैं सिर्फ एक छोटे से जंग प्रोग्राम है जो फाइबोनैचि संख्या की गणना करता है और गणना memoizes लिखा है। यह काम करता है, लेकिन मैं थोड़ा उलझन में हूं क्यों, विशेष रूप से रिकर्सिव कॉल। (यह भी शायद मुहावरेदार नहीं है।)क्यों मैं स्पष्ट रूप से एक उधार, परिवर्तनशील चर उधार देने के लिए की जरूरत नहीं है?
यहां कार्यक्रम है:
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
}
}
यहाँ मैं कैसे समझ में क्या हो रहा है:
main
में,let mut cache
का अर्थ है "मैं सक्षम होना चाहते हैं इस हैशप को म्यूटेट करने के लिए (या चर को फिर से असाइन करें) "।- जब
main
कॉलfib
, यह&mut cache
गुजरता कहते हैं "मैं आप इस उधार कर रहा हूँ, और आप इसे उत्परिवर्तित करने की अनुमति दी रहे हैं।" fib
के हस्ताक्षर में,cache: &mut Hashmap
का मतलब है "मैं एक परिवर्तनशील HashMap उधार होने की उम्मीद - उत्परिवर्तित करने के लिए अनुमति के साथ यह उधार लेने के लिए"
(कृपया मुझे ठीक कर लें मैं गलत हूँ।)
लेकिन fib
रिकर्स करता है, fib(n -1, cache)
पर कॉल करने के लिए, मुझे fib(n -1, &mut cache)
का उपयोग करने की आवश्यकता नहीं है, और अगर मैं ऐसा करता हूं तो मुझे एक त्रुटि मिलती है: "अपरिवर्तनीय स्थानीय चर cache
उत्परिवर्तनीय के रूप में उधार नहीं ले सकता"। है ना? यह एक अपरिवर्तनीय स्थानीय चर नहीं है, यह एक परिवर्तनीय उधार है - है ना?
error: mismatched types:
expected `&mut std::collections::hash::map::HashMap<i32, i32>`,
found `&&mut std::collections::hash::map::HashMap<i32, i32>`
कौन सा लगता है यह कह रही है "मैं एक परिवर्तनशील संदर्भ की उम्मीद है और एक परिवर्तनशील संदर्भ के लिए एक संदर्भ मिल गया":
अगर मैं fib(n - 1, &cache)
कोशिश, मैं एक अलग त्रुटि मिलती है।
मुझे पता है कि fib
रिकर्सिव कॉल में उधार दे रहा है क्योंकि अगर उसने स्वामित्व छोड़ दिया है, तो यह बाद में cache.insert
पर कॉल नहीं कर सका। और मुझे पता है कि इस प्रत्यावर्तन के लिए एक विशेष मामला है, अगर मैं fib2
परिभाषित fib
को लगभग समान हो सकता है, मैं उन्हें recurse एक दूसरे के माध्यम से हो सकता है और यह ठीक काम करता है क्योंकि नहीं है।
क्यों मैं स्पष्ट रूप से एक उधार, परिवर्तनशील चर उधार देने के लिए की जरूरत नहीं है?
आप स्वामित्व पास कर सकते हैं, और फ़ंक्शन उत्तर और कैश के साथ एक टुपल लौटा सकता है: [PlayPen] (http://is.gd/tUadZ0) –