Rust 如何创建具有多个实例化选项的类

Rust 如何创建具有多个实例化选项的类,rust,Rust,我想在Rust中构建一个类,该类允许其实例化的多样性和便利性,类似于std::net::TcpStream可以为其connect方法提供多个输入的方式 我进行了以下测试,但对于实现这一结果所需构建的结构或特性知之甚少 #[cfg(test)] mod test { use super::Ipv4Network; use std::net::Ipv4Addr; #[test] fn instantiation() { let net_addr =

我想在Rust中构建一个类,该类允许其实例化的多样性和便利性,类似于
std::net::TcpStream
可以为其
connect
方法提供多个输入的方式

我进行了以下测试,但对于实现这一结果所需构建的结构或特性知之甚少

#[cfg(test)]
mod test {
    use super::Ipv4Network;
    use std::net::Ipv4Addr;

    #[test]
    fn instantiation() {
        let net_addr = Ipv4Addr::new(10, 0, 0, 0);
        let net_mask = Ipv4Addr::new(255, 255, 255, 240);

        // Instantiate an Ipv4Network using two Ipv4Addrs.
        let with_addrs = Ipv4Network::new(net_addr, net_mask);

        // Instantiate an Ipv4Network using an Ipv4Addr and a prefix integer.
        let with_addr_prefix = Ipv4Network::new(net_addr, 28);

        // Instantiate an Ipv4Network using two strings.
        let with_strings = Ipv4Network::new("10.0.0.0", "255.255.255.240");

        // Instantiate an Ipv4Network using a string and a prefix integer.
        let with_prefix = Ipv4Network::new("10.0.0.0", 28);

        // Instantiate an Ipv4Network using a string with CIDR notation.
        let with_cidr = Ipv4Network::new("10.0.0.0/28");
    }
}
我的理解是,
std::net::TcpStream
通过trait完成其多个
connect
输入,可以找到trait的来源。我不清楚std::net:TcpStream::connect的确切方式,但我想我应该能够定义一个
Ipv4Network
,如下所示:

pub struct Ipv4Network {
    addr: Ipv4Addr,
    mask: Ipv4Addr,
}
如果这是真的,那么我该如何创建一个特性(比如说
ToIpv4Network
),它的功能类似于
ToSocketAddrs
std::net:TcpStream

这肉应该是什么

impl ToIpv4Network for (Ipv4Addr, Ipv4Addr) {
...
}

看起来像?这是一条正确的道路吗?

这是一个合理的起点。我认为您的问题之一是,您定义的接口将很难通过使用trait来完成

那么,让我们来谈谈
ToSocketAddrs
的工作方式。首先,让我们快速地注意到,然后忽略以下事实:
ToSocketAddrs
特性返回一个
迭代器
of
SocketAddrs
。我们之所以忽略它,是因为它实际上与手头的问题无关

以下是特质声明的主体:

pub trait ToSocketAddrs {
    type Iter: Iterator<Item=SocketAddr>;
    fn to_socket_addrs(&self) -> Result<Self::Iter>;
}
pub trait to socketaddrs{
Iter型:迭代器;
fn to_socket_addrs(&self)->结果;
}
此特性的目的是允许将其用作泛型函数/结构中的。广义地说,trait边界是一种编写泛型的方法,但是可以让Rust编译器确保最终实例化泛型的类型实现该trait(或trait)定义的行为

ToSocketAddrs
的情况下,这意味着一个类型可以(潜在地)转换为
SocketAddr
。在
connect
内部调用的代码然后使用trait上定义的
to_socket\u addrs
函数

作为一个简短的旁白,我说可能是因为
to_socket\u addrs
返回一个
结果
,它的值可以是
Ok()
Err()
,这可能是一个很好的模式来模拟你的特质

这就是为什么我认为您想要的接口可能不理想(或不可实现,Rust不直接支持算术或任何其他类型的函数重载)的关键点。传递特性绑定的泛型参数是实现目标的最简单方法