सुनिश्चित करें कि आप कर सकते हैं:
fn fun_test(value: i32, f: &dyn Fn(i32) -> i32) -> i32 {
println!("{}", f(value));
value
}
fn times2(value: i32) -> i32 {
2 * value
}
fn main() {
fun_test(5, ×2);
}
जैसा कि यह जंग है, आपको बंद के स्वामित्व और जीवनकाल को ध्यान में रखना होगा ।
टीएल; डीआर; मूल रूप से 3 प्रकार के क्लोजर (कॉल करने योग्य ऑब्जेक्ट) हैं:
Fn
: यह कैप्चर की गई वस्तुओं को संशोधित नहीं कर सकता है।
FnMut
: यह कैप्चर की गई वस्तुओं को संशोधित कर सकता है।
FnOnce
: सबसे प्रतिबंधित। केवल एक बार ही बुलाया जा सकता है क्योंकि जब इसे बुलाया जाता है तो यह अपने आप को और इसके कैप्चर को खा जाता है।
देखें कि Fn, FnMut और FnOnce को कब बंद किया जाता है? अधिक जानकारी के लिए
यदि आप क्लोजर जैसे एक साधारण पॉइंटर-टू-फंक्शन का उपयोग कर रहे हैं, तो कैप्चर सेट खाली है और आपके पास Fn
स्वाद है।
यदि आप अधिक फैंसी सामान करना चाहते हैं, तो आपको लैम्ब्डा कार्यों का उपयोग करना होगा।
जंग में कार्यों के लिए उचित संकेत हैं, जो सी में उन लोगों की तरह काम करते हैं। उनका प्रकार उदाहरण के लिए है fn(i32) -> i32
। Fn(i32) -> i32
, FnMut(i32) -> i32
और FnOnce(i32) -> i32
वास्तव में लक्षण हैं। किसी फ़ंक्शन का पॉइंटर हमेशा इन तीनों को लागू करता है, लेकिन रस्ट में भी क्लोजर होते हैं, जो कि पॉइंटर्स में परिवर्तित हो सकते हैं या नहीं हो सकते हैं (इस पर निर्भर करता है कि कैप्चर सेट खाली है) फ़ंक्शंस में हैं, लेकिन वे इन लक्षणों में से कुछ को लागू करते हैं।
तो उदाहरण के लिए, ऊपर से उदाहरण का विस्तार किया जा सकता है:
fn fun_test_impl(value: i32, f: impl Fn(i32) -> i32) -> i32 {
println!("{}", f(value));
value
}
fn fun_test_dyn(value: i32, f: &dyn Fn(i32) -> i32) -> i32 {
println!("{}", f(value));
value
}
fn fun_test_ptr(value: i32, f: fn(i32) -> i32) -> i32 {
println!("{}", f(value));
value
}
fn times2(value: i32) -> i32 {
2 * value
}
fn main() {
let y = 2;
fun_test_impl(5, times2);
fun_test_impl(5, |x| 2*x);
fun_test_impl(5, |x| y*x);
fun_test_dyn(5, ×2);
fun_test_dyn(5, &|x| 2*x);
fun_test_dyn(5, &|x| y*x);
fun_test_ptr(5, times2);
fun_test_ptr(5, |x| 2*x);
fun_test_ptr(5, |x| y*x);
}