我的目標是做最後兩行的代碼編譯,最後斷言的經過:允許函數接受`T`或任何`FnMut(T) - > T`
struct State {
string: String
}
impl State {
fn string<F: FnMut(String) -> String>(mut self, mut f: F) -> Self {
self.string = f(self.string);
self
}
}
fn main() {
let state = State { string: String::from("foo") };
assert_eq!(state.string, "foo");
let state = state.string(|old| old + "bar");
assert_eq!(state.string, "foobar");
// let state = state.string(String::from("baz"));
// assert_eq!(state.string, "baz");
}
我認爲這將是可能的特質和專業化,但下面的代碼:
#![feature(specialization)]
trait Get<T> {
fn get(self, old: T) -> T;
}
impl<T> Get<T> for T {
default fn get(self, _: T) -> T {
self
}
}
impl<T, F> Get<T> for F where F: FnMut(T) -> T {
fn get(mut self, old: T) -> T {
self(old)
}
}
struct State {
string: String
}
impl State {
fn string<G: Get<String>>(mut self, g: G) -> Self {
self.string = g.get(self.string);
self
}
}
拋出這個錯誤(live):
error[E0119]: conflicting implementations of trait `Get<_>`:
--> <anon>:13:1
|
13 | impl<T, F> Get<T> for F where F: FnMut(T) -> T {
|^
|
note: conflicting implementation is here:
--> <anon>:7:1
|
7 | impl<T> Get<T> for T {
|^
error: aborting due to previous error
所以我的問題是,爲什麼第二個impl沒有獲得比第一個更具體的「特定」,並且在當前的stable或每晚的Rust中有沒有辦法讓我的原始代碼工作?
編輯:我知道只爲一種類型實現一個特性是可行的,但我想爲任何類型的通用解決方案,因爲我希望能夠使用此結構的任何任意字段。
如果什麼'T'實現'FnMut( T) - > T'? – CodesInChaos
@CodesInChaos我希望專業化選擇'FnMut(T) - > T'的實現,但我會很高興與任何一個,因爲我不打算與這種類型的使用它。 – Dogbert