我想撰寫一些代碼,這些代碼應該是跨特定特征的實作者通用的,但直到運行時才能知道其確切型別。
特別是,我想將一個函式應用PartialOrd到給定列舉的案例子集上。這是我要實作的基本版本:
enum Value {
String(String),
Float(f64),
Array(Vec<Value>),
}
fn apply_op<T, F>(v: &Value, compare_val: &Value, op: F) -> bool
where
F: FnOnce(&T, &T) -> bool,
T: PartialOrd,
{
match (v, compare_val) {
(Value::String(s), Value::String(compare_str)) => op(s, compare_str),
(Value::Float(f), Value::Float(compare_f)) => op(f, compare_f),
_ => false,
}
}
然后類似的東西PartialOrd::gt被傳入 for op。
由于型別T是由匹配臂決定的,它不能被單態化,因此不會編譯。
有沒有辦法解決這個問題,也許是某種特征/包裝器結構?
Playground link here,其中包括上面的版本(無法編譯)和我目前用來解決這個問題的宏方法。宏作業正常,但感覺如果沒有宏,這應該是可能的。
uj5u.com熱心網友回復:
你不能后期系結一個泛型函式,但你可以為此創建一個特征:
pub trait Comparator<T> {
fn compare(self, a: &T, b: &T) -> bool;
}
然后為每個比較器創建一個型別,例如Gt:
struct Gt;
// You can also implement it individually for `String`, `f64` and `Vec<Value>`.
impl<T: PartialOrd> Comparator<T> for Gt {
fn compare(self, a: &T, b: &T) -> bool {
PartialOrd::gt(a, b)
}
}
然后:
fn apply_op<F>(v: &Value, compare_val: &Value, op: F) -> bool
where
F: Comparator<String> Comparator<f64> Comparator<Vec<Value>>,
{
match (v, compare_val) {
(Value::String(s), Value::String(compare_str)) => op.compare(s, compare_str),
(Value::Float(f), Value::Float(compare_f)) => op.compare(f, compare_f),
_ => false,
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/477881.html
上一篇:C#泛型邊界
下一篇:泛型引數放置之間的打字稿差異
