什么时候我应该在Rust库的Rust绑定中使用`& mut self`和`& self`?

时间:2016-11-18 15:12:17

标签: rust ffi

我不确定何时在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中找不到任何关于该主题的具体内容。

1 个答案:

答案 0 :(得分:5)

在这种情况下,对象是否变异是次要的;主要问题是“两个引用同时使用是否安全?”。两个线程是否可以同时在同一个对象上调用zmq_send(或其他方法),或者(如果API允许)通过嵌套回调等?

如果没有,请使用&mut self并让Rust强制执行您需要的安全保障。

如果它是安全的,那么可能&self是合适的,如果zmq保证它没问题;这就像Mutex::lock &self一样。