首页 文章

我是否必须'use'一个特征才能调用该特征中定义的方法?

提问于
浏览
3

我正在玩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'

看起来Rust编译器找不到 length() 方法,除非我导入 Vector3 使用的其中一个特征 . 深入研究source code,看起来长度方法是在 EuclideanVector 特性中定义的 .

直觉上,我不需要导入特征来使用继承所述特征的类型 . 是否有一种技术可以让我失踪?这是cgmath库特有的细微差别吗?这是Rust应该习惯的惯用语吗?

4 回答

  • 0

    你're thinking of traits in terms of inheritance. It might make more sense if you think of a trait as a module that'相对于 Self 类型是可重载的 . 从这个角度来看,特征必须在范围内,以便编译器知道它的方法,就像模块必须在范围内才能使用它一样 . 这一点的一个特殊含义是,实现可以与它们实现的特性一起声明,而不是它们实现它的类型 . 在这种情况下,很明显,如果您的代码没有使用它的方法 .

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

  • 1

    严格来说,您不必使用 use . 或者:

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

    如果您确实不想导入,可以调用 cgmath::vector::EuclideanVector::length(&mypoint) .

    (当问到这个问题时,我不知道这是否可行 . )

  • 4

    是的,这就是Rust的工作原理 . 您必须始终导入特征才能使用其方法 . 这是设计的 .

相关问题