我發現我自己的答案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
雖然它不是最小的,但我的例子是完整的和可驗證的。之所以這麼做並不輕微,是因爲我昨天在睡覺前剛剛發現了這個可靠的例子,並且不想在睡前過多的時間,但仍然希望讓別人看到它。 –