所以我想写一个这样的函数:
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
}
但这不起作用。我错过了什么?我猜有一个预先定义的特征涵盖了这个案例?即便如此,有没有办法定义它(为了学习)
答案 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 }
}