我正在玩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应该习惯的惯用语吗?
答案 0 :(得分:4)
你在继承方面考虑了特征。如果你认为特征是一个可以在Self
类型上超载的模块,那么这可能更有意义。从这个角度来看,特征必须在范围内,以便编译器知道它的方法,就像模块必须在范围内才能使用它一样。这一点的一个特殊含义是,实现可以与它们实现的特性一起声明,而不是它们实现它的类型。在这种情况下,显然如果您的代码不了解该特征,它就无法使用其方法。
当前行为的另一个动机是多个特征可以定义具有相同名称的方法,并且当对同一类型实现的特征存在此类冲突时,您不能再使用方法调用语法来访问其方法。相反,您必须使用函数调用语法来指定方法所属的特征(作为方法所在模块的特征)。如果方法调用语法使用了程序中的所有特征而不仅仅是方法解析范围内的特征,那么您更经常会遇到这些冲突,因为您的特征与特征中的方法存在名称冲突。代码实际上并没有直接使用。
答案 1 :(得分:3)
严格地说,您 不能使用use
。可替换地:
(&mypoint as &cgmath::vector::EuclideanVector).length2()
答案 2 :(得分:1)
如果您真的不想导入,可以拨打cgmath::vector::EuclideanVector::length(&mypoint)
。
(当问到这个问题时,我不知道这是否可行。)
答案 3 :(得分:0)
是的,这就是Rust的工作原理。您必须始终导入特征才能使用其方法。这是设计的。