सबसे पहले, मुझे यह कहना है कि समस्या impl Trait
वाक्यविन्यास के उपयोग से कोई लेना देना नहीं है। मैंने बंद नाम को एक नामित संरचना में परिवर्तित कर दिया और उसी परिणाम प्राप्त किए।
तो, आप करना चाहते हैं के कोड को देखो काम:
let f = apply(second, i);
let _ = tuples.iter().filter(f);
क्या संकलक कि बारे में क्या कहना है?
error[E0277]: the trait bound `for<'r> impl std::ops::FnMut<(&(_, _),)>: std::ops::FnMut<(&'r &(&str, &std::ops::Fn(i32) -> bool),)>` is not satisfied
--> <anon>:11:27
|
11 | let _ = tuples.iter().filter(f);
| ^^^^^^ trait `for<'r> impl std::ops::FnMut<(&(_, _),)>: std::ops::FnMut<(&'r &(&str, &std::ops::Fn(i32) -> bool),)>` not satisfied
error[E0277]: the trait bound `for<'r> impl std::ops::FnMut<(&(_, _),)>: std::ops::FnOnce<(&'r &(&str, &std::ops::Fn(i32) -> bool),)>` is not satisfied
--> <anon>:11:27
|
11 | let _ = tuples.iter().filter(f);
| ^^^^^^ trait `for<'r> impl std::ops::FnMut<(&(_, _),)>: std::ops::FnOnce<(&'r &(&str, &std::ops::Fn(i32) -> bool),)>` not satisfied
ठीक है, तो हमारे पास टाइप एक्स है और इसे विशेषता वाई लागू करने की आवश्यकता है लेकिन ऐसा नहीं है। लेकिन चलो बारीकी से देखें:
for<'r> impl
std::ops::FnMut<(&(_, _),)>:
std::ops::FnMut<(&'r &(_, _),)>
आह हे! filter
एक ऐसे फ़ंक्शन की अपेक्षा करता है जो एक संदर्भ को संदर्भित करता है संदर्भ में संदर्भित करता है, जबकि जिस फ़ंक्शन में हम गुजर रहे हैं वह एक ट्यूपल के संदर्भ को स्वीकार करता है। filter
एक संदर्भ के संदर्भ को पास करता है क्योंकि tuples.iter()
संदर्भों पर पुनरावृत्त करता है, और filter
इनके संदर्भों को पास करता है।
ठीक है, के संदर्भ के लिए संदर्भ को स्वीकार करने के second
की परिभाषा बदल:
fn second<'a, A, B: ?Sized>(&&(_, ref second): &&'a (A, B)) -> &'a B {
second
}
संकलक अभी भी खुश नहीं:
error[E0277]: the trait bound `for<'r> impl std::ops::FnMut<(&&(_, _),)>: std::ops::FnMut<(&'r &(&str, &std::ops::Fn(i32) -> bool),)>` is not satisfied
--> <anon>:11:27
|
11 | let _ = tuples.iter().filter(f);
| ^^^^^^ trait `for<'r> impl std::ops::FnMut<(&&(_, _),)>: std::ops::FnMut<(&'r &(&str, &std::ops::Fn(i32) -> bool),)>` not satisfied
error[E0271]: type mismatch resolving `for<'r> <impl std::ops::FnMut<(&&(_, _),)> as std::ops::FnOnce<(&'r &(&str, &std::ops::Fn(i32) -> bool),)>>::Output == bool`
--> <anon>:11:27
|
11 | let _ = tuples.iter().filter(f);
| ^^^^^^ expected bound lifetime parameter , found concrete lifetime
|
= note: concrete lifetime that was found is lifetime '_#24r
expected bound lifetime parameter , found concrete lifetime
... कि क्या मतलब है?
f
का प्रकार कुछ प्रकार है जो FnMut(&'c &'b (&'a str, &Fn(i32) -> bool)) -> bool
लागू करता है। कॉल में apply
, B == &'c &'b (&'a str, &Fn(i32) -> bool)
और C == bool
पर कॉल करें। ध्यान दें कि B
एक निश्चित प्रकार यहां है; 'c
एक, निश्चित जीवनकाल का प्रतिनिधित्व करता है, जिसे ठोस जीवनकाल कहा जाता है।
के filter
के हस्ताक्षर पर एक नज़र डालें:
fn filter<P>(self, predicate: P) -> Filter<Self, P> where
Self: Sized, P: FnMut(&Self::Item) -> bool,
यहाँ, P
FnMut(&Self::Item) -> bool
को लागू करना चाहिए। असल में, यह वाक्यविन्यास for<'r> FnMut(&'r Self::Item) -> bool
के लिए लघुरूप है। यहाँ। 'r
एक बाध्य आजीवन पैरामीटर है।
तो, समस्या हमारे समारोह है कि FnMut(&'c &'b (&'a str, &Fn(i32) -> bool)) -> bool
लागू करता नहीं लागू for<'r> FnMut(&'r Self::Item) -> bool
करता है। हमें एक ऐसे फ़ंक्शन की आवश्यकता होगी जो for<'c> FnMut(&'c &'b (&'a str, &Fn(i32) -> bool)) -> bool
लागू करे।
fn apply<A, B, C, F, G>(mut f: F, a: A) -> impl FnMut(&B) -> C
where F: FnMut(&B) -> G,
G: FnMut(A) -> C,
A: Clone
{
move |b| f(b)(a.clone())
}
या अधिक स्पष्ट संस्करण: यह करने के लिए एक ही रास्ता है, अब के लिए, apply
इस तरह लिखने के लिए होगा
fn apply<A, B, C, F, G>(mut f: F, a: A) -> impl for<'r> FnMut(&'r B) -> C
where F: for<'r> FnMut(&'r B) -> G,
G: FnMut(A) -> C,
A: Clone
{
move |b| f(b)(a.clone())
}
जंग अंततः higher-kinded types का समर्थन करता है, तो वहाँ एक हो सकता है इस समस्या को हल करने के लिए और अधिक सुरुचिपूर्ण तरीका।
मेरे उत्तर के प्रति आपकी प्रतिक्रिया के आधार पर, मेरा सुझाव है कि आप अपनी समस्या का एक [एमसीवीई] तैयार करें। शायद [इस तरह कुछ] (https://play.rust-lang.org/?gist=67472cbead98bdcdb5ea8cd92925130d)। – Shepmaster
मैंने इसे 'लागू' और 'दूसरा' करने के लिए घटा दिया - मैं एचआरटीबी की समस्या को हल करने की कोशिश कर रहा हूं। – iopq