【问题标题】:Do I have to 'use' a trait in order to call methods defined in that trait?我是否必须“使用”一个特征才能调用该特征中定义的方法?
【发布时间】:2014-10-07 13:37:48
【问题描述】:

我在玩 cgmath 库。我有以下 main.rs 文件:

extern crate cgmath;

use cgmath::vector::{Vector3, EuclideanVector};

fn main() {
    let mypoint = Vector3 { x: 1f64, y: 1f64, z: 3f64 };

    println!("The length of the vector is {}, and the length squared is {}", mypoint.length(), mypoint.length2());
}

在我的使用行中,当我省略EuclideanVector 时,出现以下编译错误:

type 'cgmath::vector::Vector3<f64>' does not implement any method in scope named 'length'

除非我导入 Vector3 使用的特征之一,否则 Rust 编译器似乎找不到 length() 方法。深入研究source code,看起来长度方法是在EuclideanVector trait 中定义的。

直观地说,我不需要导入特征来使用继承所述特征的类型。有没有一种技术可以让我失踪?这是 cgmath 库特有的细微差别吗?这是我应该习惯的 Rust 的惯用部分吗?

【问题讨论】:

标签: rust


【解决方案1】:

是的,这就是 Rust 的工作原理。在使用它的方法之前,您必须始终导入一个特征。这是设计使然。

【讨论】:

    【解决方案2】:

    您正在从继承的角度考虑特征。如果您将 trait 视为相对于 Self 类型可重载的模块,这可能更有意义。从这个角度来看,特征必须在范围内才能让编译器知道它的方法,就像模块必须在范围内才能使用它一样。这一点的一个特殊含义是,实现可以与它们实现的特征一起声明,而不是它们实现的类型。在这种情况下,很明显如果您的代码不知道该特征,它就不能使用它的方法。

    当前行为的另一个动机是多个特征可以定义具有相同名称的方法,并且当您为相同类型实现的特征发生冲突时,您不能再使用方法调用语法来访问它们的方法。相反,您必须使用函数调用语法来指定该方法是哪个特征的成员(该特征充当该方法所在的模块)。如果方法调用语法使用了程序中的所有特征,而不仅仅是方法解析范围内的特征,那么您最终会更频繁地遇到这些冲突,因为您会与代码中没有的特征中的方法发生名称冲突实际直接使用。

    【讨论】:

      【解决方案3】:

      严格来说,您没有使用use。或者:

      (&mypoint as &cgmath::vector::EuclideanVector).length2()
      

      【讨论】:

      • 这实际上是一个演员表,只有在as的右侧可以变成一个对象时才有效。
      【解决方案4】:

      如果实在不想导入,可以拨打cgmath::vector::EuclideanVector::length(&amp;mypoint)

      (我不知道在问这个问题时这是否可能。)

      【讨论】:

        猜你喜欢
        • 2015-05-29
        • 1970-01-01
        • 2013-10-30
        • 1970-01-01
        • 1970-01-01
        • 2015-01-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多