不能在其他文件 rust 中使用已实现的特征

can't use implemented trait in other file rust

所以我有两个文件 main.rs 和 utils.rs

我在 utils.rs 上实现了 StringUtils 方法,但是当我尝试在 main.rs 中使用该方法时 它给了我这个错误

error[E0599]: no method named `slice` found for reference `&str` in the current scope
  --> src\main.rs:89:50
   |
89 |         let text: String = self.inner.clone().as_str().slice(self.start, self.current);
   |                                                        ^^^^^ method not found in `&str`
   |
   = help: items from traits can only be used if the trait is implemented and in scope
note: `StringUtils` defines an item `slice`, perhaps you need to implement it
  --> src\util.rs:25:1
   |
25 | trait StringUtils {
   | ^^^^^^^^^^^^^^^^^
// main.rs

mod utils;
use utils::*;

...

    fn add_token0(&mut self, token_type: TokenType) {
        let text: String = self.inner.clone().as_str().slice(self.start, self.current);
        // error: no method named `slice` found for reference `&str` in the current scope
    }

...

但我已经在 utils.rs

上实现了它
// utils.rs

...

trait StringUtils {
    ...
    fn slice(&self, range: impl RangeBounds<usize>) -> &str;
    ...
}

impl StringUtils for str {
    ...
    fn slice(&self, range: impl RangeBounds<usize>) -> &str {
        ...
    }
    ...
}

...

为什么我的实现不起作用,有什么方法可以解决这个问题,或者我只能在 main.rs 上实现 StringUtils?

The Rust Programming Language 中的 Paths for Referring to an Item in the Module Tree 节中出现了一个实质上等效的示例(如果您还没有阅读,我建议您阅读)。

简短的版本是,模块中您希望对其他模块可见的任何项(例如特征、函数定义)都应该具有 pub 可见性修饰符的某种变体。在您的即时示例中,这表明需要使 StringUtils 特征 pub (或将其暴露给包含模块的其他变体)。

事实上,如果您尝试通过 use utils::StringUtils 而不是 glob 导入直接导入 StringUtils,您会收到以下错误消息:

error[E0603]: trait `StringUtils` is private
  --> src/lib.rs:7:12
   |
7  | use utils::StringUtils;
   |            ^^^^^^^^^^^ private trait
   |
note: the trait `StringUtils` is defined here
  --> src/lib.rs:19:5
   |
19 |     trait StringUtils {
   |     ^^^^^^^^^^^^^^^^^

link 到 this explanation 的一种修复方法。因此,如果我们改为 pub trait StringUtils { ... },则不会出现与使用特征相关的问题。

您仍然会遇到@trentcl 提到的关于 slice 的参数数量不正确的问题,我认为 self.start..self.current(或包含版本)应该是传递的范围。

最后,关于 text 的类型注释有一个错误,因为 StringUtils::slice 会 return &str,而不是 String。根据您的需要,您应该更改特征及其实现或查看 and the differences between them.

(playground).


您可能希望有一个更严格的可见性修饰符,例如 pub(crate)pub(super) 分别限制对包含板条箱或包含模块的可见性。

可以在 the relevant section in The Rust Reference 中找到更详尽的解释。