2
我希望能夠通過給變異體構造一個值,構造枚舉值創建變體:不帶參數從空的元組
use self::Variants::*;
#[derive(Clone, Debug)]
enum Variants {
Unit(()),
One(u8),
}
fn emit<C: Fn(S) -> T, S, T>(constructor: C, value: S) -> T {
constructor(value)
}
fn main() {
let unit: Variants = emit(&Unit,());
println!("{:?}", unit); // Prints Unit(()).
let one: Variants = emit(&One, 10);
println!("{:?}", one); // Prints One(10).
}
用這個例子的問題是,我需要的()
在Unit(())
代替更正常Unit
(不帶參數)。
我試着用專業化:
#![feature(specialization)]
trait Constructor<S, T> {
fn construct(self, value: S) -> T;
}
impl<T> Constructor<(), T> for T {
fn construct(self, _value:()) -> T {
self
}
}
impl<F: Fn(S) -> T, S, T> Constructor<S, T> for F {
default fn construct(self, value: S) -> T {
self(value)
}
}
fn emit<C: Constructor<I, R>, I, R>(callback: &C, value: I) -> R {
callback.construct(value)
}
use self::Variants::*;
#[derive(Clone, Debug)]
enum Variants {
Unit,
One(u8),
}
fn main() {
let unit: Variants = emit(&Unit,());
println!("{:?}", unit); // Should prints Unit.
let one: Variants = emit(&One, 10);
println!("{:?}", one); // Prints One(10).
}
但這種失敗在編譯時間:
conflicting implementations of trait `Constructor<(), _>`:
從我的RFC的瞭解,這將失敗,因爲沒有這些impl
S的一個子集另一個。我認爲這是因爲第一個impl
的for T
中的T
比第二個實現中的for F
的F
更通用。因此,它不可能是專業化的。
在另一方面,它不可能是一般的(default
)實現,因爲Constructor<(), T> for T
(甚至Constructor<S, T> for T
)比Constructor<S, T> for F
更具體,因爲T
是在前兩次寫入。
這是我從閱讀RFC的理解。請告訴我,如果我錯了。
我怎樣才能使第一個例子工作,而不必給Unit
一個無用的參數?
我很喜歡夜間編譯器的解決方案。