Почему изменение переданного Опциона внутри функции не распространяется на Опцион снаружи? - PullRequest
0 голосов
/ 15 сентября 2018

Я проиллюстрировал это так:

fn main() {

    let mut opt1 = Some(1);
    // compiler complains that opt2 doesn't have to be mutable
    let mut opt2 = Some(1);

    fn take_inner(mut opt: Option<u8>) {
        opt.take();
    };

    opt1.take();
    take_inner(opt2);

    println!("opt1 {:?}", opt1); // prints "opt1 None"
    println!("opt2 {:?}", opt2); // prints "opt2 Some(1)"

}

Rust Playground link

Почему вызов opt.take() внутри функции имеет иной эффект, чем вызов ее снаружи (относительно области действия основной функции)?

Ответы [ 2 ]

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

Поскольку u8 является типом копии, а Option имеет

impl<T> Copy for Option<T>
where
    T: Copy,

take_inner принимает копию opt2

Вы можете это исправить, взяв непостоянную ссылку:

fn main() {
    let mut opt1 = Some(1);
    // compiler complains that opt2 doesn't have to be mutable
    let mut opt2 = Some(1);

    fn take_inner(opt: &mut Option<u8>) {
        opt.take();
    };

    opt1.take();
    take_inner(&mut opt2);

    println!("opt1 {:?}", opt1);
    println!("opt2 {:?}", opt2);
}

Ссылка на игровую площадку

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

Когда T: Copy, то так же Option<T>. Это означает, что при передаче его в качестве аргумента функции:

take_inner(opt2);

фактически скопирует данные. Если бы T не было Copy, то ничего из этого не сработало бы, потому что вместо этого было бы перемещено , поэтому вы даже не могли бы напечатать его позже.

Если вы передадите его в качестве изменяемой ссылки, то функция может изменить исходное значение:

fn take_inner(opt: &mut Option<u8>) {
    opt.take();
};

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