何时/为什么需要使用/导入Rust Traits

4

什么时候/为什么需要使用/导入Rust特性(trait),或者为什么这个问题没有意义?

我是一名有经验的程序员,但我是Rust的新手。

我正在阅读《Rust编程语言》--在第2章中有以下声明。

首先,我们添加一个 use 行:use rand::RngRng 特性定义了随机数生成器实现的方法,必须让该特性处于当前作用域才能使用这些方法。第10章将详细介绍特性。

重���强调。

我不清楚为什么这个程序

use std::io;
use rand::Rng;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_number);

    println!("Please input your guess.");

    let mut guess = String::new();

    io::stdin()
        .read_line(&mut guess)
        .expect("Failed to read line");

    println!("You guessed: {}", guess);
}

需要使用 rand::Rng。当我们使用/导入 std::io 符号时,我们可以访问一个io符号,我们可以在其上调用关联函数。

io::stdin

在我天真(且错误)的看法中,使用use rand::Rng会给我们一个Rng符号。但实际上,我们得到了一个rand符号,我们可以在其上调用thread_rng方法。
let secret_number = rand::thread_rng().gen_range(1, 101);

我的天真看法是,为了调用thread_rng,我们需要像这样做
use rand;
// or
use rand::rand

当我在程序中使用use rand::Rng时,作为程序员的我在做什么?这与use std::io有何不同?
1个回答

4
rand "符号"是一个外部 crate 的名称,它在根名称空间中,与任何 use 语句无关。它定义了一个函数 thread_rng(),可以通过添加命名空间前缀 rand:: 调用,即使没有use语句也同样适用。
因此,即使没有使用use语句,你也可以执行以下操作:
let thread_rng = rand::thread_rng();

然而,thread_rng 返回一个 rand::rngs::ThreadRng 结构,你试图在它上面调用 gen_range,但是 这个 函数是一个 trait 方法,只有通过使用 use 语句导入 rand::Rng trait 才能使用。
实际上,即使没有 use 语句,也可以调用 trait 方法:
rand::Rng::gen_range(&mut rand::thread_rng(), 1, 101);

...但总的来说,use 更加简洁。


1
ThreadRng 是否实现了 Rng 特性的 gen_range 方法?我在 rand crate 中找不到任何证据。 即使是这样,为什么我们在结构体上定义了方法后仍然需要使用特性呢?是为了帮助 Rust 进行命名空间限定吗? - Shridharshan
我已经阅读了文档,我的理解是对于任何实现了RngCore trait的类型,Rng trait都会自动实现。这回答了我在上面评论中提出的第一个问题,尽管我不确定我的理解是否正确。 - Shridharshan
因此,为了使用模块,调用者被迫知道类型实现的特征是哪个?即使没有冲突?Rust 很奇怪。 - Donglei
哦,我明白了。pub mod trait 可以解决这个问题。 - Donglei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接