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

When should I use `&mut self` vs. `&self` in Rust bindings for a C library?

我不确定在 libzmq C API.

的 Rust 绑定中何时使用 &mut self 与仅使用 &self

一些背景知识:libzmq 提供了套接字"objects",它有一个类似于BSD套接字API的API,在C中用一个不透明的指针表示。这个指针实际上只是一个句柄,类似于 POSIX 文件描述符,并且 C API 的设计使得它 not 不可能获得对它背后的内存的任何引用指针。

在这种情况下,API 设计使用不可变 self 公开套接字方法是否安全且良好?作为具体示例,请考虑 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::io::Write::write(),由 std::net::TcpStream 实施。另一方面,std::net::UdpStream::write() 只需要 &self。我的猜测是 &mut self 被使用只是因为它是 Write 特征的实现,反过来(我猜)使用 &mut self 来不限制特征的实现。

我希望有人能在这里支持或反驳我的推测——我在本书或 Nomicon 中找不到关于该主题的任何具体内容。

在这种情况下对象是否发生变异是次要的;主要问题是"is it safe for two references to be used at the same time?"。两个线程同时调用同一对象上的 zmq_send(或其他方法),或者(如果 API 允许)通过嵌套回调等,是否可以?

如果不是,请使用 &mut self 并让 Rust 执行您需要的安全保证。

如果安全的话,也许&self是合适的,如果zmq保证没问题;这就像 Mutex::lock 占用 &self.