Rust 对可变选项内的值调用方法

Rust 对可变选项内的值调用方法,rust,Rust,我有一个可变的选项类型,我试图在中对一些进行变异,但我不知道如何做 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"); }

我有一个可变的
选项
类型,我试图在
中对一些
进行变异,但我不知道如何做

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");
    }
}

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

您可以直接匹配
选项,如下所示(显示
i32
而不是
TcpStream
):

structfoo{
流:选项,
}
impl-Foo{
fn发送(&M自我){
匹配self.stream{
一些(参考mut x)=>{
*x=0;
}
无=>{}
}
}
}
(不确定这是否是最惯用的方法。)

正如,
if let
比迭代
选项更好,而且更惯用:

#[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);
}
impl Foo {
    fn send(&mut self) {
        for x in self.stream.as_mut() {
            *x += 1;
        }
    }
}
在此之前,我通常会使用:

其他选择 正如弗拉基米尔·马特维耶夫(再次!)指出的那样,
map
通常用于转换数据,而不是用于副作用(我同意这一点)。您可以使用
iter\u mut
(或者
&mut collection
的缩写),因为我觉得迭代通常是为了产生副作用。我喜欢这样,因为这意味着我们的代码可以避免有条件的:

impl Foo {
    fn send(&mut self) {
        for x in &mut self.stream {
            *x += 1;
        }
    }
}
您还可以利用
IntoIterator实现
选项

#[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);
}
impl Foo {
    fn send(&mut self) {
        for x in self.stream.as_mut() {
            *x += 1;
        }
    }
}
作为后续操作,还可以使用if-let语法:

struct Foo {
    stream: Option<i32>,
}

impl Foo {
    fn send(&mut self) {
        if let Some(ref mut x) = self.stream {
            *x = 0;
        }
    }
}
structfoo{
流:选项,
}
impl-Foo{
fn发送(&M自我){
如果let Some(ref mut x)=self.stream{
*x=0;
}
}
}

我还认为这比
map()
更惯用,因为
map()
方法是用来转换
选项的,而不是执行副作用(赋值是副作用)。

map
是用来转换选项的”-一个有趣的观点,我可能会同意。但是,为什么您会认为
as_mut
存在?我想不出它会被用于其他任何事情……好吧,这取决于你使用它的上下文。我当然可以想象一个API想要获得
选项
。或者它可以与
Option::Or()
和一些默认目标一起使用:
self.optional\u vector.as\u mut().或(&mut self.other\u vector).push(123)
。选项用途非常广泛:)我想可能是
as_mut
map
的组合没有真正结合在一起。出于好奇,我做了一个快速搜索,只看到一个
map
改变了它的参数。是的,这可能是因为这个测试是在
if-let
登陆之前很久编写的:)而且它仍然是功能门控的,尽管这很快就会改变。对于其他读者来说:我对这篇文章的“if-let”部分有点盲目。不要错过
as_mut
,这才是真正的宝石,让您可以访问
选项
的内部,而无需使用它。
struct Foo {
    stream: Option<i32>,
}

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