我对 Rust 很陌生,我刚刚花了一个下午的时间来研究 Rust 中的以下实现问题。
这是我的不同文件:
Foo.rs
struct Foo {
socket: TCPSocket
}
TCP.rs(
Option
字段在开始时并未定义,因此它们被初始化为None
)
pub struct TCPSocket{
client_address: Option<SocketAddr>,
server_address: SocketAddr,
status: SocketStatus,
stream: Option<TCPStream>,
listener: Option<TCPListener>,
type: SocketType, //Either Client or Server
}
impl TCPSocket{
pub write(&self)
pub read(&self)
pub connect(&self)
pub bind_and_listen(&self)
pub accept(&self)
}
所以现在我的问题是:我发现这个实现有点糟糕。套接字的类型包含在一个字段中,如果有客户端套接字,则不应访问某些方法/属性(例如
bind_and_listen
和 accept
或 client_address
)。如何改进这段代码?
所以一开始,我认为一个好的解决方案是将结构分为两部分:一个用于客户端套接字,另一个用于服务器套接字。然而,这两个结构共享一些方法/属性。在对 StackOverflow 进行一些研究之后,解决方案是创建一个名为 BaseSocket 的子结构,它将实现所有共享属性/方法,并将该子结构作为 Client 和 Server 结构中的属性。但是,如果我这样做,我需要创建两种类型的 Foo(一种用于客户端,一种用于服务器),而我不希望这样。
之后我想到的解决方案是将 Client 和 Socket 重新组合到一个枚举中,以便我可以将此枚举传递给 Foo 结构。我不太喜欢这个解决方案的是 Foo 结构的用户已经知道他在 Foo 中拥有什么类型的套接字。当程序运行时,会创建两个 Foo,一个带有客户端套接字,一个带有服务器套接字,它们在代码的两个不同部分中使用。因此,每当他想要使用套接字的方法时,他都必须使用
match
,即使他知道他正在使用哪种变体。socket
,然后调用所需的不同方法,即使他已经知道他正在使用服务器。当一个人知道自己在做什么时,我发现使用 match
真的很奇怪。
我不确定我是否清楚地解释了自己,但我只是找不到一个完全合乎逻辑的方法来实现这一点。我知道在其他语言中,我可以有一个名为
Socket
的母类,其中包含所有共享属性/方法。然后,我可以有两个子类,一个用于客户端,一个用于具有特定方法/属性的服务器。有了这些,我只需要给 Foo 母亲类的类型,因为女儿也是母亲类型,所以它会起作用。但我在 Rust 中找不到这样一个合乎逻辑的方式。
正如我所说,我对这种语言很陌生,所以也许我遗漏了一些东西,但如果有人有解决方案,请启发我:)。
在 TCP 中,服务器套接字与客户端套接字不同。 它们具有不同的输入和不同的功能。
由于这些原因,这两个功能必须区别对待,因此必须单独实现。
所有主要编程语言的库都遵循这种分离,包括 Rust。
推荐方法:维护两个不同的结构 - 一个用于 TCP 服务器,另一个用于TCP 客户端