2015-09-01 4 views
2

Это код, который я пытаюсь выполнить:не может двигаться из заимствованного контента, когда разворачивания окна

fn my_fn(arg1: &Option<Box<i32>>) -> (i32) { 
    if arg1.is_none() { 
     return 0; 
    } 
    let integer = arg1.unwrap(); 
    *integer 
} 

fn main() { 
    let integer = 42; 
    my_fn(&Some(Box::new(integer))); 
} 

(on the Rust playground)

Я получаю следующее сообщение об ошибке:

error[E0507]: cannot move out of borrowed content 
--> src/main.rs:5:19 
    | 
5 |  let integer = arg1.unwrap(); 
    |     ^^^^ cannot move out of borrowed content 

Я вижу, что уже есть много документации по вопросам проверки чеков, но после прочтения я все еще не могу понять проблему.

Почему это ошибка и как ее решить?

ответ

3

Option::unwrap() использует этот параметр, т. Е. Принимает значение по значению. Однако у вас нет значения, у вас есть только ссылка на него. Вот что такое ошибка.

Ваш код должен идиоматический быть записан следующим образом:

fn my_fn(arg1: &Option<Box<i32>>) -> i32 { 
    match *arg1 { 
     Some(ref b) => **b, 
     None => 0, 
    } 
} 

fn main() { 
    let integer = 42; 
    my_fn(&Some(Box::new(integer))); 
} 

(on the Rust playground)

Или вы можете использовать Option комбинаторы как Option::as_ref или Option::as_mut сопряженных с Option::map_or как Shepmaster предложил:

fn my_fn(arg1: &Option<Box<i32>>) -> i32 { 
    arg1.as_ref().map_or(0, |n| **n) 
} 

Этот код использует тот факт, что i32 автоматически копируется. Если тип внутри Box не был Copy, то вы бы не смогли получить внутреннее значение по значению вообще - вы могли бы только его клонировать или возвращать ссылку, например, как здесь:

fn my_fn2(arg1: &Option<Box<i32>>) -> &i32 { 
    static ZERO: i32 = 0; 
    arg1.as_ref().map_or(&ZERO, |n| n) 
} 

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

+0

А что, если я хочу получить ссылку на i32 внутри коробки (скажем, я хочу ее изменить и иметь другую часть программы, чтобы увидеть измененное значение)? – Moebius

+1

FWIW, я бы написал его как 'arg1.as_ref(). Map (| x | ** x) .unwrap_or (0)' – Shepmaster

+0

@Shepmaster, спасибо! –

 Смежные вопросы

  • Нет связанных вопросов^_^