Tha*_*tos 3 enums type-inference rust
此示例无法编译:
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() {}
Run Code Online (Sandbox Code Playgroud)
此版本中的错误是:
error[E0531]: unresolved tuple struct/variant `Inet`
--> match_arms.rs:14:3
|
14 | Inet(addr) => addr.to_std(),
| ^^^^
Run Code Online (Sandbox Code Playgroud)
交换Inet注释掉的行成功编译.
编译器似乎要求我指定枚举类型本身,我想这样它就知道我在matcharm中指定的变体是合法的.但为什么?不能推断出枚举吗?编译器是否有足够的信息来实现这nix_addr是一个nix::…::SocketAddr,因此,这Inet是一个有效的变量(和一个有数据)?
为什么我要输出整个内容,或者将名称拖入当前范围use?
我也试过_::Inet,也失败了.
根据引入枚举命名空间的RFC 390,这个推理被认为是一个黑客,并没有更好的设计.从RFC的替代部分:
我们可以在1.0之后通过添加"回退"案例来实现枚举命名空间,如果没有其他定义在该命名空间中发生冲突,则可以从其"平面"定义位置引用变体.在保持向后兼容性的黑客计划中,这并不是那么糟糕,但仍然比不必担心后备更糟糕.
在RFC 390之后没有考虑推理的官方原因是没有人真正关心提出改变:
@netvl Java是一个有趣的案例,你只能在语句中引用"裸"形式(
FOO,而不是MyEnum.FOO)的变体switch.Rust中的情况稍微复杂一些,因为它match允许比传统switch语句更强大的模式匹配.最接近的模拟可能是隐含地处理在模式中导入的所有相关内容.这似乎与这个提议足够正交,它可能值得拥有自己的RFC.
(从那时起,没有人为此编写过RFC.)
但是,这样一个RFC通过的机会很小.毕竟,您只需要在use nix::sys::socket::SockAddr::*某处添加一行即可使其正常工作.在语言中添加一个功能需要考虑正确的规范和极端情况(例如,当您发生的情况use nix::sys::socket::SockAddr::Unix as Inet),这可能不值得花时间.
| 归档时间: |
|
| 查看次数: |
265 次 |
| 最近记录: |