减少深度嵌套属性的匹配缩进

fad*_*bee 1 pattern-matching algebraic-data-types rust

我需要引用结构深处的值,该结构包含Option嵌套在struct属性中的嵌套在Result.

我目前的(工作)解决方案是:

    let raw = &packet[16..];
    match PacketHeaders::from_ip_slice(raw) {
        Err(_value) => {
            /* ignore */
        },
        Ok(value) => {
            match value.ip {
                Some(Version4(header)) => {
                    let key = format!("{}.{}.{}.{},{}.{}.{}.{}", 
                        header.source[0], header.source[1], header.source[2], header.source[3],
                        header.destination[0], header.destination[1], header.destination[2], header.destination[3],
                    );

                    let Count {packets, bytes} = counts.entry(key).or_insert(Count {packets: 0, bytes: 0});
                    *packets += 1;
                    *bytes += packet.len();

                    if p > 1000 { /* exit after 1000 packets */
                        for (key, value) in counts {
                            println!("{},{},{}", key, value.packets, value.bytes);
                        }
                        return ();
                    }
                    p += 1;
                }
                _ => {
                    /* ignore */
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

(我当前代码的问题是过度嵌套和两个匹配。)

我想要的只是PacketHeaders::from_ip_slice(ip) >> Ok >> ip >> Some >> Version4

我怎样才能得到这个,或者很好地忽略每个捕获的数据包的故障(不是崩溃/退出)?

mca*_*ton 5

模式匹配嵌套,而 struct 的模式看起来像结构文字,附加..意思是“并匹配所有其余的,我不在乎”,类似于_模式的含义“匹配任何内容”。意思是你可以

match PacketHeaders::from_ip_slice(raw) {
    Ok(PacketHeaders { ip: Version4(header), .. }) => {
        /* handle */
    }
    _ => {
        /* ignore `Err(_)` and other `Ok(_)` */
    },
}
Run Code Online (Sandbox Code Playgroud)

如果您要忽略除一种情况之外的所有情况,则可以使用if let

match PacketHeaders::from_ip_slice(raw) {
    Ok(PacketHeaders { ip: Version4(header), .. }) => {
        /* handle */
    }
    _ => {
        /* ignore `Err(_)` and other `Ok(_)` */
    },
}
Run Code Online (Sandbox Code Playgroud)