Why do I need to import a trait to use the methods it defines for a type?
RustRust Problem Overview
I have a very simple example of Rust code which fails to compile:
extern crate rustc_serialize;
use rustc_serialize::base64;
fn main() {
let auth = format!("{}:{}", "user", "password");
let auth_b64 = auth.as_bytes().to_base64(base64::MIME);
println!("Authorization string: {}", auth_b64);
}
The compiler error:
error[E0599]: no method named `to_base64` found for type `&[u8]` in the current scope
--> src/main.rs:6:36
|
6 | let auth_b64 = auth.as_bytes().to_base64(base64::MIME);
| ^^^^^^^^^
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope, perhaps add a `use` for it:
candidate #1: `use rustc_serialize::base64::ToBase64;`
It works if I import the trait explicitly:
extern crate rustc_serialize;
use rustc_serialize::base64::{self, ToBase64};
fn main() {
let auth = format!("{}:{}", "user", "password");
let auth_b64 = auth.as_bytes().to_base64(base64::MIME);
println!("Authorization string: {}", auth_b64);
}
Why do I need to use rustc_serialize::base64::ToBase64;
?
Rust Solutions
Solution 1 - Rust
That’s simply the way it is. In Rust a trait must be in scope for you to be able to call its methods.
As for why, the possibility of collisions is the reason why. All the formatting traits in std::fmt
(Display
, Debug
, LowerHex
, &c.) have the same method signature for fmt
. For example; what would object.fmt(&mut writer, &mut formatter)
do, for example? Rust’s answer is “you must explicitly indicate by having the trait in scope where the method is.”
Note also how the error message says that “no method named `m` found for type `T` in the current scope”.
Note that you don't have to import it if you want to use the trait method as a function instead of a method:
extern crate rustc_serialize;
use rustc_serialize::base64;
fn main() {
let auth = format!("{}:{}", "user", "password");
let auth_b64 = rustc_serialize::base64::ToBase64::to_base64(auth.as_bytes(), base64::MIME);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
println!("Authorization string: {}", auth_b64);
}