मैं पारित फ़ंक्शन की "जेनेरिकनेस" को खोए बिना किसी अन्य फ़ंक्शन (इस मामले में बंद) में एक सामान्य फ़ंक्शन पास करने में सक्षम होना चाहता हूं। ,तर्क के रूप में जेनेरिक फ़ंक्शन पास करें
use std::fmt::Debug;
fn test<F, I: Debug>(gen: F) where F: Fn(fn(I) -> I) -> I {
fn input<I: Debug>(x: I) -> I {
x
}
println!("{:?}", gen(input));
}
fn main() {
test(|input| {
input(10);
input(10.0)
});
}
यह संकलन नहीं करेगा क्योंकि input
का मूल्य inferenced टाइप और अब सामान्य है: चूंकि कि एक बहुत जटिल बयान है, यहाँ एक उदाहरण है।
पूर्ण त्रुटि:
<anon>:14:15: 14:19 error: mismatched types:
expected `_`,
found `_`
(expected integral variable,
found floating-point variable) [E0308]
<anon>:14 input(10.0)
^~~~
जंग में ऐसी बात संभव है?
संपादित करें:
समाधान के आधार पर दिया जाता है, मैं का उपयोग किया है एक ऐसी ही समस्या का समाधान करने के लिए निम्न:
#![feature(unboxed_closures)]
#![feature(fn_traits)]
use std::ops::Fn;
use std::ops::Add;
use std::ops::FnMut;
use std::fmt::Debug;
struct Builder;
impl Builder {
pub fn build<A: Add<B>, B: Add<A>>(&self) -> fn(A, B) -> <A as std::ops::Add<B>>::Output {
fn c<A: Add<B>, B: Add<A>>(a: A, b: B) -> <A as std::ops::Add<B>>::Output {
a + b
}
return c;
}
}
impl<A: Add<B>, B: Add<A>> Fn<(A, B)> for Builder {
extern "rust-call" fn call(&self, args: (A, B)) -> <A as std::ops::Add<B>>::Output {
let (a1, a2) = args;
self.build()(a1, a2)
}
}
impl<A: Add<B>, B: Add<A>> FnMut<(A, B)> for Builder {
extern "rust-call" fn call_mut(&mut self, args: (A, B)) -> <A as std::ops::Add<B>>::Output {
let (a1, a2) = args;
self.build()(a1, a2)
}
}
impl<A: Add<B>, B: Add<A>> FnOnce<(A, B)> for Builder {
type Output = <A as std::ops::Add<B>>::Output;
extern "rust-call" fn call_once(self, args: (A, B)) -> <A as std::ops::Add<B>>::Output {
let (a1, a2) = args;
self.build()(a1, a2)
}
}
fn test<F, I: Debug>(gen: F) where F: Fn(Builder) -> I {
let b = Builder;
println!("{:?}", gen(b));
}
fn main() {
test(|builder| {
builder(10, 10);
builder(10.1, 10.0)
});
}
जंग खेल का मैदान लिंक: https://play.rust-lang.org/?कोड = उपयोग% 20std% 3A% 3Afmt% 3A% 3ADebug% 3 बी% 0A% 0Afn% 20test% 3CF% 2C% 20I% 3A% 20Debug% 3E (जनरल% 3A% 20F)% 20where% 20F% 3A% 20Fn (fn (आई)% 20% 3E% 20I)% 20% 3E% 20I% 20% 7B% 0A% 20% 20% 20% 20fn% 20input% 3CI% 3A% 20Debug% 3E (एक्स% 3A% 20I)% 20% 3E% 20I% 20% 7B% 0A% 20% 20% 20% 20% 20% 20% 20% 20x% 0A% 20% 20% 20% 20% 7 दिन% 0A% 20% 20% 20% 20 % 0A% 20% 20% 20% 20println! (% 22% 7B% 3A% 3F% 7 दिन% 22% 2C% 20gen (इनपुट))% 3 बी% 0A% 7 दिन% 0A% 0Afn% 20main()% 20% 7B % 0A% 20% 20% 20% 20test (% 7Cinput% 7C% 20% 7B% 0A% 20% 20% 20% 20% 20% 20% 20% 20input (10)% 3 बी% 0A% 20% 20% 20 % 20% 20% 20% 20% 20 इनपुट (10.0)% 0 ए% 20% 20% 20% 20% 7 डी)% 3 बी% 0 ए% 7 डी और संस्करण = स्थिर और बैकट्रैक = 0 – dpzmick
मुझे यकीन है कि यह कभी काम नहीं करेगा? आप 'test' को कॉल कर रहे हैं जिसे 'जीन' बंद करने के पहले कॉल की अनुमान के आधार पर u32 होने के लिए monomorphized किया जाएगा। यदि आप एक अलग चाहते हैं .. आपको फिर से 'टेस्ट' कॉल करना होगा .. अलग से। मैं इसे अपने सिर में "संकलित" कर रहा हूं और मैं नहीं देखता कि यह या किसी अन्य भाषा में कैसे संभव होगा, क्योंकि अनुमान कम हो जाएगा। शायद मैं गलत हूँ हालांकि। –