【问题标题】:Why do I need to import a trait to use the methods it defines for a type?为什么我需要导入一个特征来使用它为一个类型定义的方法?
【发布时间】:2014-10-06 02:01:09
【问题描述】:

我有一个非常简单的无法编译的 Rust 代码示例:

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

编译器错误:

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;`

如果我明确导入特征,它会起作用:

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

为什么我需要use rustc_serialize::base64::ToBase64;

【问题讨论】:

  • 请注意,从 Rust 1.33 开始,如果您不需要使用其名称来引用 trait,您可以像 use Trait as _; 一样导入它。这有助于解决名称冲突。

标签: rust


【解决方案1】:

就是这样。在 Rust 中,必须在范围内才能调用其方法。

至于为什么,碰撞的可能性就是原因。 std::fmt 中的所有格式特征(DisplayDebugLowerHex 等)对于 fmt 具有相同的方法签名。例如;例如,object.fmt(&mut writer, &mut formatter) 会做什么? Rust 的回答是“你必须通过在方法所在的范围内明确指出 trait。”

还要注意错误消息是如何说“在当前范围内没有为类型 `T` 找到名为 `m` 的方法”。

请注意,如果您想将 trait 方法用作函数而不是方法,则不必导入它:

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

【讨论】:

  • 这是否也允许编译器将剩余的方法排除在发布之外,从而创建更紧凑的程序?
  • @Jackalope:如果仅通过静态分派(泛型)使用特征,则只会编译使用的代码。如果您使用动态分派(特征对象),则所有特征方法都将是(理论上它可以确定只使用了某些方法,从而从 vtable 中逐出未使用的方法,但我不相信使用了这样的优化。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-12
相关资源
最近更新 更多