Каков наилучший способ ссылки на статический метод из другого статического метода того же класса в Rust? - PullRequest
0 голосов
/ 03 сентября 2018

В новом модуле Rust я могу написать:

struct myStruct {
    x : u32
}

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

    fn other() -> u32 {
        6
    }
}

Исходя из других ОО-языков, я ожидаю, что other() будет в области действия new(). То есть я ожидал, что смогу вызвать один статический метод класса из другого статического метода того же класса. Однако 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 ]

0 голосов
/ 03 сентября 2018

Дизайнеры Rust сделали следующий выбор: все, что связано с областью применения, является явным. Таким образом, так же, как вы должны набрать self для вызова функции-члена из другой функции-члена: self.foo(), вы должны вызвать статический член с Self: 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

Затем команда сделала выбор в пользу полной ясности, чтобы сохранить грамматику связной.

0 голосов
/ 03 сентября 2018

Да, это так, потому что ржавчина - это не Java;)

Вы можете написать:

myStruct { x: myStruct::other() }

или

myStruct { x: Self::other() }

Я не могу сказать вам точное проектное решение, почему функции Self не импортируются автоматически, но вы можете обойти это, используя правильный путь.

...