繁体   English   中英

为什么不能在比赛武器中推断出枚举变体?

[英]Why can't enum variants be inferred in match arms?

此示例无法编译:

extern crate nix;
use std::os::unix::io::RawFd;

fn func(fd: RawFd, buf: &mut [u8]) -> Result<(), nix::Error> {
    let (size, nix_addr) = nix::sys::socket::recvfrom(
        fd, buf
    )?;

    let addr = match nix_addr {
        //nix::sys::socket::SockAddr::Inet(addr) => addr.to_std(),
        Inet(addr) => addr.to_std(),
        _ => panic!(),
    };

    Ok(())
}

fn main() {}

此版本中的错误是:

error[E0531]: unresolved tuple struct/variant `Inet`
  --> match_arms.rs:14:3
   |
14 |        Inet(addr) => addr.to_std(),
   |        ^^^^

交换注释掉的Inet线成功编译。

编译器似乎要求我指定枚举类型本身,我想它知道我在match臂中指定的变体是合法的。 但为什么? 不能推断出枚举吗? 编译器是否有足够的信息来实现nix_addr是一个nix::…::SocketAddr ,因此, Inet是一个有效的变量(和一个有数据的变量)?

我为什么要出去键入整个事情,或拖动名称与一个当前范围use

我也试过_::Inet ,也失败了。

  • 但为什么? 不能推断出枚举吗?

根据引入枚举命名空间的RFC 390 ,这个推理被认为是一个黑客,并没有更好的设计。 从RFC的替代部分:

我们可以在1.0之后通过添加“回退”案例来实现枚举命名空间,如果没有其他定义在该命名空间中发生冲突,则可以从其“平面”定义位置引用变体。 在保持向后兼容性的黑客计划中,这并不是那么糟糕, 但仍然比不必担心后备更糟糕。

在RFC 390之后没有考虑推理的官方原因是没有人真正关心提出改变:

@sfackler

@netvl Java是一个有趣的案例,你只能在switch语句中引用“裸”形式的变体( FOO ,而不是MyEnum.FOO )。 Rust的情况有点复杂,因为match允许比传统的switch语句更强大的模式匹配。 最接近的模拟可能是隐含地处理在模式中导入的所有相关内容。 这似乎与这个提议足够正确, 它可能值得拥有自己的RFC。

(从那时起,没有人为此编写过RFC。)

但是,这样一个RFC通过的机会很小。 毕竟,你只需要在某处添加一行use nix::sys::socket::SockAddr::*来使其工作。 在语言中添加一个特性需要考虑正确的规范和use nix::sys::socket::SockAddr::Unix as Inet情况(例如,当你use nix::sys::socket::SockAddr::Unix as Inet时会发生什么)它可能不值得花时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM