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

56
8

У меня есть функция find определенная в базовом решении для хранения в памяти. Я пытаюсь найти способ гибко пройти условные параметры поиска, создав struct под названием SearchOpts:

trait HasRecords {
fn find(&self, opts: &SearchOpts) -> ();
}

pub struct SearchOpts {
sensorId: Option<String>,
}

struct MemDb {
id: u32,
}

impl HasRecords for MemDb {
fn find(&self, opts: &SearchOpts) -> () {
println!("Hello {}", opts.sensorId.unwrap());
}
}

fn main() {
let _x = MemDb { id: 42 };
}

детская площадка

error[E0507]: cannot move out of borrowed content
--> src/main.rs:15:30
|
15 | println!("Hello {}", opts.sensorId.unwrap());
| ^^^^ cannot move out of borrowed content

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

спросил(а) 2018-07-04T00:54:00+03:00 2 года назад
1
Решение
55

Ключ в том, что, поскольку у вас есть только ссылка на структуру SearchOpts в вашей функции, вы не можете выйти из нее.

Рассматривая определение Option::unwrap:

pub fn unwrap(self) -> T

Он принимает аргумент Option по значению, поэтому он будет перемещаться из структуры. Не хорошо! Ключом к его устранению является Option::as_ref:

pub fn as_ref(&self) -> Option<&T>

Как следует из подписи, он преобразует &Option<T> в Option<&T>. Этот последний тип может быть развернут (что приводит к &T), не двигая ничего. Поэтому вы можете написать:

if opts.sensorId.is_some() && &d.sensorId != opts.sensorId.as_ref().unwrap() {
return false;
}

Однако я бы написал так:

if opts.sensorId.as_ref().map_or(false, |id| id != &d.sensorId) {
return false;
}

ответил(а) 2018-07-04T01:03:00+03:00 2 года назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема