rust - 你如何在 Rust 的通用特征上实现特定类型?

标签 rust

我最初认为您可以这样做,因为文档 ( 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 Fooimpl Bar<uint> for Foo是一个错误,因为目前只有一个 impl每个特征都允许,类型对(忽略特征上的参数)。 I went into more detail in this answer ,包括解决使用次要特征的工作,避免必须制作 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) }
}

第二个错误是因为你有两个类型参数 TU new 的“范围内”函数,但只指定一个 ( U )。 T需要写明Foo::<int>::... ,但是我认为这不是您想要的,相反,您应该使用 Tnew 中通用功能:

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 .

关于rust - 你如何在 Rust 的通用特征上实现特定类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24771274/

相关文章:

serialization - 颠覆 Rust 的类型系统以进行 printf 风格的调试

json - 我可以使用类型来表示构造函数的至少一个参数应该是 Some 吗?

rust - 为什么不能将&str传递给接受&dyn Display特征对象的函数?

docker - SSL 证书验证适用于 Docker,而不适用于 Kubernetes

rust - 将静态字符串传递给rust中的macro_rule

rust - 从 HashMap 或 Vec 返回引用会导致借用超出其所在范围?

rust - 无法在PE0 STM32上接收中断

rust - 如何在 Rust 的内循环中正确移动所有权?

rust - 简单的 Rust crate 函数整数/ float 错误

rust - 用相同的值替换Rust中的变量会产生不同的结果