在Rust中,最佳的方式是如何从同一类的另一个静态方法引用静态方法?

14
在一个新的Rust模块中,我可以写:
struct myStruct {
    x : u32
}

impl myStruct {
    fn new() -> myStruct{
        myStruct{ x : other()}
    }

    fn other() -> u32 {
        6
    }
}

作为一个来自其他面向对象编程语言的开发者,我原本期望在new()内能够调用other()的方法。也就是说,我期望能够从同一类的另一个静态方法中调用一个静态方法。然而,rustc会输出以下错误信息:

error[E0425]: cannot find function `other` in this scope
 --> dummy_module.rs:9:23
  |
9 |         myStruct{ x : other()}
  |                       ^^^^^ not found in this scope

相比之下,以下Java代码可以顺利编译:

public class myStruct{
    int x;

    public myStruct(){
        x = other();
    }

    private int other(){
        return 5;
    }
}

我不记得在我使用的 Rust 书中看到有关这个的提及,而且我似乎找不到清晰的在线答案。 我可以通过明确地将调用限定在 myStruct::other() 中来修复它,但这似乎很麻烦。 如果我尝试使用 use myStruct,那么我会收到神秘的消息。

7 |     use myStruct;
  |     ^^^ unexpected token

这种显式作用域始终是必需的吗?如果是,为什么?

我是否做错了什么?是否有惯用的解决方法?


2
Rust并不像Java一样是一个真正的“面向对象”语言。如果你试图用Rust写Java,你会遇到很多问题。 - Wesley Wiser
4
这与面向对象语言无关,只是一道关于语法的问题。 - Stargateur
2个回答

24

Rust 的设计者做出了以下选择:与作用域有关的所有内容都是显式的。因此,就像你必须键入 self.foo() 来从另一个成员函数调用成员函数一样,你必须使用 Self::bar() 调用静态成员。

我认为之所以如此,是因为 self 不能是隐式的:实际上它必须作为参数按值或借用方式添加,而不像 Java 中的 this 总是按值传递。因此,由于 self 已经是显式参数,为了保持一致性,需要它作为显式调用者。

由于 Rust 的内存模型,显式性允许提供更好的错误消息。例如,考虑以下代码:

struct Struct;

impl Struct {
    fn foo(&mut self) {
        self.consume();
    }

    fn consume(self) {}
}

错误信息为:

error[E0507]: cannot move out of borrowed content
 --> src/main.rs:5:9
  |
5 |         self.consume();
  |         ^^^^ cannot move out of borrowed content

然后团队决定完全明确以保持语法连贯。


1
我找不到任何证据来支持我的说法。显式的 self 从2012年开始实现:https://github.com/rust-lang/rust/pull/3974,在那个时候还没有RFC。 - Boiethios
1
请注意,其他编程语言(例如Python)在Rust出现之前就已经为方法明确指定了self参数,这可能影响了Rust的设计。 - Jmb

8
是的,这是有意为之的,因为Rust不是Java ;)
你只需要写:
myStruct { x: myStruct::other() }

或者

myStruct { x: Self::other() }

我无法告诉你为什么Self函数不会自动导入,这是一个设计决策。但你可以通过使用正确的路径来“解决”这个问题。

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