在python中,我可能有一个看起来像这样的类:
class ClientObject(object):
def __init__(self):
connection = None
connected = False
def connect(self):
self.connection = new Connection('server')
self.connected = True
def disconnect(self):
self.connection.close()
self.connection = None
self.connected = False
Run Code Online (Sandbox Code Playgroud)
我正在尝试做类似生锈的事情.首先,我怀疑这是否是一个生锈的好模式 - 你会用这种方式实现一个连接的客户端类吗?其次,我收到一个错误,我不理解我的实现.
pub struct Client {
seq: int,
connected: bool,
socket: Option<UdpSocket>
}
impl Client {
pub fn connect(&mut self, addr: &SocketAddr) -> ClientConnectionResult {
match self.socket {
Some(_) => self.disconnect(),
None => ()
};
self.socket = match UdpSocket::bind(*addr) {
Ok(s) => Some(s),
Err(e) => return Err(to_client_error(e))
};
self.connected = true;
Ok(())
}
pub fn disconnect(&mut self) {
match self.socket {
None => (),
Some(s) => drop(s)
};
self.socket = None;
self.connected = false;
}
}
Run Code Online (Sandbox Code Playgroud)
在disconnect函数中,匹配会生成编译错误,因为它会尝试移动self.socket的所有权.我想要做的是将self.socket设置为None,并允许稍后在调用connect时将其重新分配给某些内容.我该怎么办?
它可能不适用于您的用例,但Rust移动语义和强类型允许廉价的"状态机",当方法消耗self(当前状态)并返回另一个表示另一个状态的对象时.这是如何TcpListener实现的:它具有listen()返回的方法,TcpAcceptor在进程中消耗原始侦听器.这种方法具有键入的优点:当对象处于无效状态时,您无法调用无意义的方法.
在你的情况下,它可能看起来像这样:
use std::kinds::markers::NoCopy;
pub struct DisconnectedClient {
seq: int,
_no_copy: NoCopy
}
impl DisconnectedClient {
#[inline]
pub fn new(seq: int) -> DisconnectedClient {
DisconnectedClient { seq: seq, _no_copy: NoCopy }
}
// DisconnectedClient does not implement Copy due to NoCopy marker so you need
// to return it back in case of error, together with that error, otherwise
// it is consumed and can't be used again.
pub fn connect(self, addr: &SocketAddr) -> Result<ConnectedClient, (DisconnectedClient, IoError)> {
match UdpSocket::bind(*addr) {
Ok(s) => Ok(ConnectedClient { seq: self.seq, socket: s }),
Err(e) => Err((self, e))
}
}
}
pub struct ConnectedClient {
seq: int,
socket: UdpSocket
}
impl ConnectedClient {
#[inline]
pub fn disconnect(self) -> DisconnectedClient {
// self.socket will be dropped here
DisconnectedClient::new(self.seq)
}
// all operations on active connection are defined here
}
Run Code Online (Sandbox Code Playgroud)
您首先创建DisconnectedClient使用DisconnectedClient::new()方法.然后,当您想要连接到某个东西时,您使用connect()方法,该方法使用DisconnectedClient并返回新对象ConnectedClient,它表示已建立的连接.完成此连接后,disconnect()方法将ConnectedClient返回DisconnectedClient.
这种方法可能更复杂,但它具有静态检查错误状态的优点.你没有必要connected()的方法; 如果您的变量是类型ConnectedClient,那么您已经知道它已连接.
| 归档时间: |
|
| 查看次数: |
5125 次 |
| 最近记录: |