我最初认为您可以这样做,因为文档(http://doc.rust-lang.org/rust.html#implementations)建议您可以:
trait Bar<T> {
fn ex(&self) -> T;
}
struct Foo {
y:f64
}
impl Bar<int> for Foo {
fn ex(&self) -> int {
return self.y.floor() as int;
}
}
impl Bar<uint> for Foo {
fn ex(&self) -> uint {
if (self.y < 0.0) {
return 0u;
}
return self.y.floor() as uint;
}
}
...但这似乎不起作用。我收到如下错误:
error: multiple applicable methods in scope
error: expected Bar<uint>, but found Bar<int> (expected uint but found int)
error: expected Bar<int>, but found Bar<uint> (expected int but found uint)
所以我想也许Foo必须是通用的才能起作用,所以每个特定的Foo都有自己的Bar实现:
trait Bar<T> {
fn ex(&self) -> T;
}
struct Foo<T> {
y:f64
}
impl<T> Foo<T> {
fn new<U>(value:f64) -> Foo<U> {
return Foo { y: value } as Foo<U>;
}
}
impl Bar<int> for Foo<int> {
fn ex(&self) -> int {
return self.y.floor() as int;
}
}
impl Bar<uint> for Foo<uint> {
fn ex(&self) -> uint {
if (self.y < 0.0) {
return 0u;
}
return self.y.floor() as uint;
}
}
fn main() {
let z = Foo::new::<int>(100.5);
let q = Foo::new::<uint>(101.5);
let i:int = z.ex();
let j:uint = q.ex();
}
...但是我的构造函数似乎不起作用:
x.rs:11:12: 11:38 error: non-scalar cast: `Foo<<generic #1>>` as `Foo<U>`
x.rs:11 return Foo { y: value } as Foo<U>;
^~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
编辑:我也尝试过:
impl<T> Foo<T> {
fn new<U>(value:f64) -> Foo<U> {
let rtn:Foo<U> = Foo { y: value };
return rtn;
}
}
解决了投放错误,但导致:
x.rs:32:11: 32:26 error: cannot determine a type for this expression: unconstrained type
x.rs:32 let z = Foo::new::<int>(100.5);
^~~~~~~~~~~~~~~
O_o我不知道那是什么意思。
你怎么做到这一点?
的impl Bar<int> for Foo
和impl Bar<uint> for Foo
是因为,在该时刻只能有一个错误impl
时每性状,类型对允许的(在忽略特征参数)。我在此答案中进行了更详细的介绍,包括围绕使用辅助特征的工作,该特征避免了必须使用Foo
泛型(这可能不是您想要的)。
trait BarForFoo {
fn do_ex(foo: &Foo) -> Self;
}
impl BarForFoo for int {
fn do_ex(foo: &Foo) -> int {
foo.y.floor() as int
}
}
impl BarForFoo for uint {
fn do_ex(foo: &Foo) -> uint {
foo.y.max(0.0).floor() as uint
}
}
impl<T: BarForFoo> Bar<T> for Foo {
fn ex(&self) -> T { BarForFoo::do_ex(self) }
}
第二个错误是因为您有两个类型参数T
和U
该new
函数的“范围内” ,但是仅指定一个(U
)。在T
通过书面指定的需求Foo::<int>::...
,但我不认为这是你想要的东西,相反,你应该使用T
一般的new
功能:
impl<T> Foo<T> {
fn new(value: f64) -> Foo<T> { ... }
}
作为背景,编译器需要知道的具体类型,T
因为的实现new
可能会改变:
impl<T> Foo<T> {
fn new<U>(value:f64) -> Foo<U> {
Foo { y: value + std::mem::size_of::<T>() as f64 }
}
}
然后Foo::<()>::new::<int>(0.0)
会付出y == 0.0
,但Foo::<u64>::new::<int>(0.0)
会付出y == 8.0
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句