«Ожидаемая ссылка, найден struct Rc» при клонировании и возврате Rc - PullRequest
0 голосов
/ 28 апреля 2018

У меня есть такой код:

use std::cell::RefCell;
use std::rc::Rc;

struct A(bool);

impl A {
    fn get_ref(&self) -> &Rc<RefCell<bool>> {
        &Rc::new(RefCell::new(self.0))
    }

    fn copy_ref(&self) -> &Rc<RefCell<bool>> {
        Rc::clone(self.get_ref())
    }
}

fn main() {
    let a = A(true);
    a.copy_ref();
}

и я получил предупреждение с жалобой на то, что функция Rc::clone не получает ссылку:

error[E0308]: mismatched types
  --> src/main.rs:12:9
   |
12 |         Rc::clone(self.get_ref())
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found struct `std::rc::Rc`
   |
   = note: expected type `&std::rc::Rc<std::cell::RefCell<bool>>`
              found type `std::rc::Rc<std::cell::RefCell<bool>>`

Я работал над этим всю ночь, но не могу заставить его работать. Метод get_ref уже напечатан как возвращающий &Rc<RefCell<bool>>, но почему компилятор выдаст ошибку?

1 Ответ

0 голосов
/ 28 апреля 2018

Ошибка не в аргументе, который вы указали в Arc::clone(), а в целом выражении Rc::clone(...), тип которого отличается (Rc<...>) от типа, возвращаемого вашей функцией (&Rc<...>).

Если вы передали неправильный аргумент Rc::clone, он бы выглядел так:

  --> src/main.rs:13:19
   |
13 |         Rc::clone(false)
   |                   ^^^^^ expected reference, found bool
   |
   = note: expected type `&std::rc::Rc<_>`
              found type `bool`

Таким образом, наивный способ исправить ошибку типа - написать &Rc::clone(...). Тогда последнее выражение вашей функции будет иметь тот же тип, что и объявленный тип возврата вашей функции. Но, как вы заметите, впоследствии вы получите другие ошибки.

Давайте сделаем шаг назад, чтобы увидеть, что ваш подход здесь некорректен. Наиболее важный момент см. В «Есть ли способ вернуть ссылку на переменную, созданную в функции?» . Спойлер: ты действительно не хочешь. Поэтому конструкции, подобные вашему get_ref(), просто не имеют смысла, так как вы возвращаете ссылку на переменную, которую вы создаете внутри своей функции (переменная типа Rc).

В вашем случае прямое решение, вероятно, довольно простое: просто удалите ссылку. Rc<T> уже является указателем / ссылочным типом, поэтому нет необходимости (вообще) иметь ссылку на него.

Однако, поскольку вы используете Rc, вы, вероятно, заинтересованы в подсчете ссылок. Поэтому в этом случае вам, вероятно, не следует создавать новый Rc каждый раз, когда вызывается функция. В противном случае вы можете получить кучу Rc с количеством ссылок 1, что не совсем так. Поэтому вместо этого ваш тип A должен уже хранить Rc<RefCell<bool>>.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...