Do I have to "use" a trait in order to call the methods defined in that trait?

I am playing with the cgmath library . I have the following main.rs file:

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());
}

      

On my use string, when I omit EuclideanVector

, I am assigned the following compilation error:

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

      

It looks like the Rust compiler can't find the method length()

unless I import one of the characteristics it uses Vector3

. The output to the source code looks like this: the length method is defined within EuclideanVector

.

Intuitively, I don't need to import a trait in order to use a type that inherits the specified trait. Is there a way to make me miss? Is this a nuance specific to the cgmath library? Is this the idiomatic part of Rusti that I should be used to?

+3


source to share


4 answers


You're thinking about traits in terms of inheritance. This might make sense if you think of a trait as a module that is overloaded with respect to type Self

. From this point of view, it makes sense that this attribute must be in scope so that the compiler can learn about its methods, just as a module must be in scope to use it. A special consequence of this is that implementations can be declared with the trait they implement, rather than the type for which they implement. In this situation, if your code does not know about the trait, it cannot use its methods.



Another motivation for the current behavior is that multiple traits can define methods with the same name, and when you have such a conflict for traits implemented for the same type, you can no longer use method call syntax to access them. methods. Instead, you need to use function call syntax to specify which trait is its element (a trait that acts like the module in which the method resides). If the method invocation syntax used all the traits in your program, not just those in the scope of method resolution, you would encounter these conflicts much more often, since you would have name conflicts with methods in the traits that don't actually match your code. using directly.

+4


source


Strictly speaking, you don't need to use use

. As an alternative:



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

      

+3


source


If you really don't want to import, you can call cgmath::vector::EuclideanVector::length(&mypoint)

.

(I don't know if this is possible when the question was asked.)

+1


source


Yes, that's how Rusta works. You must always import a trait before you can use its methods. This is by design.

0


source







All Articles