我正在玩一些Rust trait和泛型来熟悉语言。
fn main() {
println(test(6f).to_str());
}
enum Result<TS,TE>{
Success(TS),
Error(TE)
}
impl<TS: ToStr, TE: ToStr> ToStr for Result<TS,TE> {
fn to_str(&self) -> ~str {
match *self {
Success(s) => s.to_str(),
Error(e) => e.to_str()
}
}
}
fn test(x:float) -> Result<float,int> {
match x {
0f..5f => Success(x/5f),
_ => Error(1i)
}
}
使用上面的代码,我得到了下面的一行。
C: 用户mflamer Dropbox 生锈测试项目 生锈。拉尔夫-舒马赫:27:8:27:13错误:移出不可变&的解引用;指针C:UsersmflamerDropboxRust项目测试 生锈。Rs:27 match *self
^~~~~
即使没有trait上的泛型,它也能很好地构建。这是怎么回事?
编辑:如果我把代码改成这样,它就可以工作了。不知道为什么。enum Result<TS,TE>{
Success{ value:TS },
Error{ error:TE }
}
impl<TS: ToStr, TE: ToStr> ToStr for Result<TS,TE> {
fn to_str(&self) -> ~str {
match *self {
Success{ value: value } => value.to_str(),
Error{ error: error } => error.to_str()
}
}
}
fn test(x:float) -> Result<float,int> {
match x {
0f..5f => Success{ value: x/5f },
_ => Error{ error: 1i }
}
}
问题在于匹配和泛型如何相互作用。下面的代码可以工作:
impl<TS: ToStr, TE: ToStr> ToStr for Result<TS,TE> {
fn to_str(&self) -> ~str {
match *self {
Success(ref s) => s.to_str(),
Error(ref e) => e.to_str()
}
}
}
(唯一的区别是ref
s)
这意味着s
和e
是指向self
内部的指针,即它们的类型是&TS
和&TE
,而不是TS
和TE
。
没有泛型的ref
不能工作的原因是int
和float
是隐式可复制的,所以s
和e
只是从self
中复制出来的,而对于任意泛型,Rust不能自动复制。