Rust:定义比较长度的泛型函数的特征

时间:2014-12-15 05:09:02

标签: generics rust

所以我想写一个这样的函数:

fn is_longer_than<T>(thing: T, threshold: int) -> bool {
    thing.len() > threshold 
}

我对一般的生锈和静态类型/泛型非常陌生,但据我所知,你需要约束T一个特性,在这种情况下,实现方法len < / p>

我试着这样做:

trait HasLength {
    fn len(&self) -> int
}

fn is_longer_than<T>(thing: HasLength, threshold: int) -> bool {
    thing.len() > threshold 
}

但这不起作用。我错过了什么?我猜有一个预先定义的特征涵盖了这个案例?即便如此,有没有办法定义它(为了学习)

1 个答案:

答案 0 :(得分:4)

您需要将T限制在特征HasLength,这是通过<T: HasLength>等语法完成的。

trait HasLength {
    fn len(&self) -> int;
}

fn is_longer_than<T: HasLength>(thing: T, threshold: int) -> bool {
    thing.len() > threshold 
}

这声明函数is_longer_than采用任何具有T实现的HasLength类型。请注意,您必须为可能要传递给impl的每种类型定义一个实现(is_longer_than)。

或者,该函数可以定义为:

fn is_longer_than2(thing: &HasLength, threshold: int) -> bool {
    thing.len() > threshold 
}

这声明了一个带有特征对象的函数,该对象包括对数据的引用和对特征的动态分派表的引用。您仍然需要定义适当的impl才能创建特征对象。

两种形式之间的区别在于第一种形式将专门用于每种类型,也就是说,将为与该函数一起使用的每种类型编译不同版本的函数。第二种形式更像是像Java这样的语言的OO代码 - 只编译一个版本的函数,但是这个版本必须使用动态调度表来调用len

以下是HasLength特征的示例impl,它将i32的长度定义为表示它所需的基数为10的数字:

impl HasLength for i32 {
  fn len(&self) -> int { self.to_string().len() as int }
}