< 返回版块

eric642 发表于 2021-12-18 20:39

请问各位大佬, 在使用rand crate时, 需要先把Rng这个trait导入本地作用域里..否则就会提示找不到gen() 这个让我有点茫然.

use rand::Rng;

fn main() {
    let s: i32 = rand::thread_rng().gen();
}

评论区

写评论
作者 eric642 2021-12-19 01:10

谢谢大佬的详细解答. 今天又学到了

👇
苦瓜小仔: 任何定义在 trait 里的方法,在使用的时候都必须引入作用域。

实际上,你遇到的这种情况在 Rust 中随处可见。

苦瓜小仔 2021-12-18 23:57

任何定义在 trait 里的方法,在使用的时候都必须引入作用域。

实际上,你遇到的这种情况在 Rust 中随处可见。

比如以下代码:playground

#![feature(type_name_of_val)]

fn main() {
    let mut iter = 0..2;
    dbg!(iter.next());

    next(&mut iter);

    dbg!(std::any::type_name_of_val(&iter));
}

fn next<I>(i: &mut I)
where
    I: Iterator,
    I::Item: std::fmt::Debug,
{
    dbg!(i.next());
}

可以正常运行,是因为:

  1. iter 作为 std::ops::range::Range<i32> 类型,它实现了 Iterator trait,所以才可以调用 .next() 方法
  2. Iterator trait 是被预先引入
  3. i.next() 可以被运行,是因为有 这个 实现
  4. dbg! 可以打印实现了 Debug trait 的变量名及其值,但其内部调用相关方法,可以无需引入当前作用域
  5. next 泛型函数需要在签名中使用 trait,所以手动引入(或者通过路径使用) Debug trait
苦瓜小仔 2021-12-18 22:50

对的。泛型方法都是这么找的。

作者 eric642 2021-12-18 20:52

脑子转过来, 看了下源码, 大概是因为:

  1. Rng trait里的都是默认方法.
  2. impl<R: RngCore + ?Sized> Rng for R {} 这里为实现了RngCore和?Sized的类型实现了 Rng 这个trait.
  3. thread_rng()返回的ThreadRng结构体实现了RngCore

综上: 因为ThreadRng只是实现了RngCore, 而gen()是Rng trait里的默认方法, 所以需要use rand::Rng才能使用这个默认方法, 不然编译器也不知道这个方法是定义在哪里的..

大约应该是这个原因吧....不知道有没有大佬指点下.

1 共 4 条评论, 1 页