我发现我自己的答案my own question为以下为什么对实现Fn特征的特征的引用不可调用?
trait Mu<T> {
fn unroll(&self, &Mu<T>) -> T;
}
impl<T, F:Fn(&Mu<T>) -> T> Mu<T> for F {
fn unroll(&self, o:&Mu<T>) -> T { self(o) }
}
fn y<T, F:Fn(T) -> T>(f:&F) -> T {
(&|w:&Mu<T>| { w.unroll(w) }).unroll(&|w:&Mu<T>| { f(w.unroll(w)) })
}
它编译和充分回答了这个问题。但要使它更漂亮,我实现了Fn
性状Mu<T>
如下所示:
impl<'a, T> Fn<&'a Mu<T>> for &'a Mu<T> {
extern "rust-call" fn call(&self, o: &'a Mu<T>) -> T {
self.unroll(o)
}
}
impl<'a, T> FnMut<&'a Mu<T>> for &'a Mu<T> {
extern "rust-call" fn call_mut(&mut self, o: &'a Mu<T>) -> T {
self.unroll(o)
}
}
impl<'a, T> FnOnce<&'a Mu<T>> for &'a Mu<T> {
type Output = T;
extern "rust-call" fn call_once(self, o: &'a Mu<T>) -> T {
self.unroll(o)
}
}
与功能
#![feature(fn_traits)]
#![feature(unboxed_closures)]
我想写Y组合为
fn y1<T, F:Fn(T) -> T>(f:&F) -> T {
(&|w:&Mu<T>| { w(w) })(&|w:&Mu<T>| { f(w(w)) })
}
但这不编译。错误消息:
rustc 1.19.0-nightly (78d8416ca 2017-06-17)
error[E0618]: expected function, found `&Mu<T>`
--> <anon>:36:20
|
36 | (&|w:&Mu<T>| { w(w) })(&|w:&Mu<T>| { f(w(w)) })
| ^^^^
|
note: defined here
--> <anon>:36:8
|
36 | (&|w:&Mu<T>| { w(w) })(&|w:&Mu<T>| { f(w(w)) })
| ^
error[E0618]: expected function, found `&Mu<T>`
--> <anon>:36:44
|
36 | (&|w:&Mu<T>| { w(w) })(&|w:&Mu<T>| { f(w(w)) })
| ^^^^
|
note: defined here
--> <anon>:36:30
|
36 | (&|w:&Mu<T>| { w(w) })(&|w:&Mu<T>| { f(w(w)) })
| ^
为什么Rust无法弄清楚给出Fn
的实现?有没有办法改善这一点?
进一步的尝试表明它与这些功能无关,甚至与闭包有关。即使Shepmaster在答案中显示的示例也不是最小的。一个最小的例子是类似如下:
trait T1 {}
trait T2 {}
impl<'a> T1 for &'a T2 {}
struct S {}
impl T2 for S {}
fn main() {
let t2: &T2 = &S {};
let t1: &T1 = &t2; //This is OK
let t3: &T1 = t2; //E0308: Expecting `T1`, found `T2`
}
是我们努力实现的一个特征对象引用一个特点,那么我们就需要添加额外的基准转换性状物体进入的一个特征对象时的问题目标特质。
请检查[MCVE]是什么,为什么它很重要,以及如何创建一个。例如,您的整个示例可以[详细说明](https://play.integer32.com/?gist=00b2e53268e0527e43aade845148195b&version=nightly)。 – Shepmaster
虽然它不是最小的,但我的例子是完整的和可验证的。之所以这么做并不轻微,是因为我昨天在睡觉前刚刚发现了这个可靠的例子,并且不想在睡前过多的时间,但仍然希望让别人看到它。 –