在可变选项内的值上调用方法

kel*_*oti 3 rust

我有一个可变的Option类型,我试图改变内部的东西,Some但我无法弄清楚如何做到这一点.

use std::net::TcpStream;
use std::io::Write;

struct Foo {
    stream: Option<TcpStream>,
}

impl Foo {
    fn send(&mut self) {
        self.stream.map(|x| x.write(b"test")).expect("Couldn't write");
    }
}
Run Code Online (Sandbox Code Playgroud)

这会产生错误:

error[E0596]: cannot borrow immutable argument `x` as mutable
  --> src/main.rs:10:29
   |
10 |         self.stream.map(|x| x.write(b"test")).expect("Couldn't write");
   |                          -  ^ cannot borrow mutably
   |                          |
   |                          consider changing this to `mut x`
Run Code Online (Sandbox Code Playgroud)

有人可以尝试实施send一个例子来帮助我理解吗?

She*_*ter 13

正如弗拉基米尔·马特维耶夫所指出的那样,if let甚至更好,并且比迭代更为惯用Option:

#[derive(Debug)]
struct Foo {
    stream: Option<i32>,
}

impl Foo {
    fn send(&mut self) {
        if let Some(ref mut x) = self.stream {
            *x += 1;
        }
    }
}

fn main() {
    let mut f = Foo { stream: Some(0) };
    println!("{:?}", f);

    f.send();
    println!("{:?}", f);
}
Run Code Online (Sandbox Code Playgroud)

虽然我通常使用Option::as_mut:

impl Foo {
    fn send(&mut self) {
        if let Some(x) = &mut self.stream {
            *x += 1;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

其他选择

正如Vladimir Matveev指出的那样(再次!),map通常用于转换数据,而不是副作用(我同意).你可以改用iter_mut,因为我觉得迭代通常用于副作用.我喜欢这个,因为这意味着我们的代码可以避免有条件:

impl Foo {
    fn send(&mut self) {
        if let Some(x) = self.stream.as_mut() {
            *x += 1;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您还可以利用&mut collection:

impl Foo {
    fn send(&mut self) {
        for x in &mut self.stream {
            *x += 1;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Vla*_*eev 5

作为@ idupree变体的后续内容,也可以使用if-let语法:

struct Foo {
    stream: Option<i32>,
}

impl Foo {
    fn send(&mut self) {
        if let Some(ref mut x) = self.stream {
            *x = 0;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我还认为这是比更地道map(),因为map()方法用于转化Option,不执行副作用(和分配一个副作用).