使用现有绑定的 Rust 模式匹配?

3

我从昨天开始学习 Rust。下面的代码很简单 --

use encoding_rs::Encoding;
use std::fs;
use std::fs::File;
use std::io::BufReader;
use std::io::Read;
use std::option::Option;
use std::path::Path;

extern crate encoding_rs;
extern crate encoding_rs_io;

fn main() {
    let mut reader = BufReader::new(file);
    let mut bom: [u8; 3] = [0; 3];

    // read BOM
    if let Ok(_) = reader.read_exact(&mut bom) {
        // sniff BOM

        // Because Rust disallows NULLs, hence I declare `Option<&Encoding>` to store the result of encoding.
        let mut enc: Option<&Encoding> = None;
        match Encoding::for_bom(&bom) {
            Some((encoding, _)) => {
                // <-- Some((enc, _))
                enc = Some(encoding);
            }
            None => {
                if let Some(encoding) = Encoding::for_label("UTF-8".as_bytes()) {
                    enc = Some(encoding);
                }
            }
        }

        if let Some(encoding) = enc {
            println!("{:?}", encoding);
        }
    }
}

它打开一个文本文件,并通过解析BOM(字节顺序标记)来尝试分析其编码。如果Encoding::for_bom未返回编码,则默认使用UTF-8

我不喜欢unwrap(),因为它总是假定有有效的结果。

我的问题是:是否有一种方法进行模式匹配并将结果直接放入现有的可变绑定中?

例如,将Some((encoding, _))更改为Some((enc,_)),因此我不需要enc = Some(encoding)这一行。

2个回答

6
许多Rust构造可以用作表达式,即它们可以返回一个值。因此,如果您的match的每个分支都返回相同类型的值,则可以直接将其赋值给变量。除非您计划稍后更改它,否则不需要将其设置为可变。
let mut reader = BufReader::new(file);
let mut bom: [u8; 3] = [0; 3];

if let Ok(_) = reader.read_exact(&mut bom) {
    let enc = match Encoding::for_bom(&bom) {
        Some((encoding, _)) => Some(encoding),
        None => Encoding::for_label("UTF-8".as_bytes()),
    };

    if let Some(encoding) = enc {
        println!("{:?}", encoding);
    }
}

2
我会使用 mapor_else 的组合:
let enc = Encoding::for_bom(&bom)
    .map(|t| t.0)
    .or_else(|| Encoding::for_label ("UTF-8".as_bytes()));

或者(更清晰但略长):
let enc = Encoding::for_bom(&bom)
    .map(|(e, _)| e)
    .or_else(|| Encoding::for_label ("UTF-8".as_bytes()));

同样是好答案。在这种情况下,组合子和手动编写的“match”最终长度几乎相同,因此选择哪个取决于个人喜好。 - michalsrb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接