我不确定何时在libzmq C API的Rust绑定中使用&mut self
与仅&self
。
一些背景知识:libzmq提供了socket"对象",它们具有类似于BSD套接字API的API,并且由C中的不透明指针表示。这个指针实际上只是一个句柄,类似到POSIX文件描述符,并且C API的设计使得不可以获得对该指针后面的内存的任何引用。
在这些情况下,使用不可变self
公开套接字方法是否安全且良好的API设计?举一个具体的例子,考虑zmq_send()
:
int zmq_send (void *socket, void *buf, size_t len, int flags);
我认为它可以(并且应该)使用不可变的自我来暴露,即:
pub fn send(&self, data: &[u8], flags: i32) -> Result<()> { ... }
但是,类似的Rust标准库方法使用&mut self
,例如由std::net::TcpStream
实施的std::io::Write::write()
。另一方面,std::net::UdpStream::write()
只需&self
。我的猜测是使用&mut self
只是因为它是Write
特征的一个实现,反过来(我猜)使用&mut self
来限制特征的实现。
我希望有人可以在这里备份或驳斥我的推测 - 我在书中或Nomicon中找不到任何关于该主题的具体内容。
答案 0 :(得分:5)
在这种情况下,对象是否变异是次要的;主要问题是“两个引用同时使用是否安全?”。两个线程是否可以同时在同一个对象上调用zmq_send
(或其他方法),或者(如果API允许)通过嵌套回调等?
如果没有,请使用&mut self
并让Rust强制执行您需要的安全保障。
如果它是安全的,那么可能&self
是合适的,如果zmq
保证它没问题;这就像Mutex::lock
&self
一样。