【问题标题】:Optional function argument that is specified as a trait instead of a concrete type指定为特征而不是具体类型的可选函数参数
【发布时间】:2014-12-03 23:19:04
【问题描述】:

过去几个月我一直在关注 Rust,但我才刚刚开始进行一个实际项目。我不确定标题中的术语是否正确。请告诉我如何纠正它。

我正在围绕 ENet 库 (http://enet.bespin.org) 编写一个 rust 包装器。我的目标是使 rust API 尽可能与 C API 相似,除了重构将 C 样式句柄指针转换为结构对象的成员函数的函数。我想保持 API 相似,以便官方 C 文档同样适用于 rust wrapper。

ENet 公开了一个函数来创建客户端主机或服务器主机。创建服务器时,您将指向 IP 地址结构的指针传递给函数。创建客户端时,您传递 NULL。

我正在尝试使用 ToSocketAddr 特征和 Option 来模拟这种行为,但将它们结合使用时会遇到问题。

这是我正在尝试做的一个简化示例:

use std::io::net::ip::ToSocketAddr;

fn create_host<A: ToSocketAddr>(addr: Option<A>) {
    match addr {
        Some(a) => println!("Address is {}. Return a server host object.",a.to_socket_addr()),
        None    => println!("no address... Return a client.")
    };
}


fn main() {
    create_host(Some("localhost:12345"));
    create_host(None);
}

第一次调用create_host() 就像一个魅力。但是,第二次调用不会编译。

Rustc 返回

error: unable to infer enough type information about `_`; type annotations required

我猜这个错误正在发生,因为None 没有为通用A 提供任何解决方案。我尝试了以下方法,但这也不起作用,因为ToSocketAddr 没有实现特征core::kinds::Sized

fn create_host(addr: Option<ToSocketAddr>) {
    ...
}

有什么方法可以做到这一点,还是我需要采取不同的方法?

【问题讨论】:

    标签: rust enet


    【解决方案1】:
    fn main() {
        create_host(Some("localhost:12345"));
        create_host(None::<&str>);
    }
    

    我在这里选择了&amp;str,因为它与第一次调用时的类型相同,因此编译器不会生成泛型函数的另一个单态版本。你可以选择任何实现ToSocketAddr的类型。

    【讨论】:

    • 谢谢,成功了!在之前的任何示例中,我都没有看到应用于None 的语法。您是否有任何链接可以准确解释其工作原理/方式?
    • 参见 Rust 参考中的 PathsGeneric functionsNone 不是泛型函数,而是泛型/多态常量,但类型参数列表语法仍然适用。
    • 谢谢,那些帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多