![](/img/trans.png)
[英]How can I use enum in a trait and implement trait on structs that are in the enum? Rust
[英]How can I use a Rust enum, struct, trait or anything else to construct a value containing an existential type?
什么Rust構造可以大致完成與以下OCaml相同的任務?
type t = F : 'x * ('x -> string) -> t
let int_eg = F(1, string_of_int)
let str_eg = F("foo", fun x -> x)
let print x = print_string (match x with
| F(x,to_str) -> to_str x)
與存在性類型最接近的是特征對象:
// how ToString is declared
trait ToString {
fn to_string(&self) -> String;
}
let i32_str: Box<ToString> = Box::new(1);
let str_str: Box<ToString> = Box::new("foo");
fn print(value: &ToString) -> String {
value.to_string()
}
print_x(&i32_str); // automatically coerced from Box<ToString> to &ToString
print_x(&str_str);
對於特征對象,實際類型將被刪除,唯一剩下的就是知道該特定值是實現給定特征的某種類型。 它與Haskell中具有類型類邊界的存在類型非常相似:
data Showable = Showable (forall a. Show a => a)
沒有辦法將任意函數與任意類型捆綁在一起,從容器簽名中刪除它,因此您需要為其使用特征。 幸運的是,特征可以輕松地為任意類型定義和實現,因此您始終可以定義特征並使用特征對象。 特性對象涵蓋了ML / Haskell中通常需要存在性的幾乎所有功能。
而且,在許多情況下,您根本不需要使用特征對象! 例如,上面的print()
函數實際上應編寫如下:
fn print<T: ToString>(value: &T) -> String {
value.to_string()
}
該函數功能更強大,因為它可與ToString
trait的任意實現程序一起使用,該實現程序包括由ToString
trait對象,以及實現ToString
所有其他功能。 通常,唯一使用特征對象的地方是定義異構數據結構時:
let many_to_strings: Vec<Box<ToString>> = vec![Box::new(1), Box::new("foo")];
但是,就像我上面說的那樣,當您使用特征對象時,在大多數情況下,您無需指定需要特征對象-常規的泛型函數會更慣用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.