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

我应该在什么时候使用`&;mut self`vs.`&;C库的Rust绑定中的self`?,rust,ffi,Rust,Ffi,我不确定何时在libzmq C API的Rust绑定中使用&mut self而不是仅使用&self 一点背景知识:libzmq提供了套接字“对象”,它有一个类似于BSD套接字API的API,并由一个不透明的C指针表示。这个指针实际上只是一个句柄,类似于POSIX文件描述符,而C API的设计使得不可能在该指针后面获得任何内存引用 在这种情况下,使用不可变的self公开套接字方法是否安全且良好的API设计?作为一个具体的例子,考虑: 我认为它可以(也应该)使用不可变的self公开,即: pub f

我不确定何时在libzmq C API的Rust绑定中使用
&mut self
而不是仅使用
&self

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

在这种情况下,使用不可变的
self
公开套接字方法是否安全且良好的API设计?作为一个具体的例子,考虑:

我认为它可以(也应该)使用不可变的self公开,即:

pub fn send(&self, data: &[u8], flags: i32) -> Result<()> { ... }
pub-fn-send(&self,数据:&[u8],标志:i32)->结果{…}
但是,可比较的Rust标准库方法使用
&mut self
,例如,由
std::net::TcpStream
实现。另一方面,
std::net::UdpStream::write()
只需
和self
。我猜想使用
&mut self
仅仅是因为它是
写入
特性的实现,而这反过来(我猜想)使用
&mut self
来不约束特性的实现


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

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

如果没有,请使用
&mut self
,让锈迹强制执行您需要的安全保证


如果它是安全的,那么可能
&self
是合适的,如果
zmq
保证它是安全的;这类似于
Mutex::lock
获取
&self

相关信息:。在这种情况下,操作系统会处理底层文件描述符的多次使用,因此没有理由在Rust中强制执行。我应该补充一点,有问题的套接字选项不是线程安全的,但是如果绑定没有实现
同步
线程,类型系统应该禁止跨线程共享,对吗?而且libzmqcapi根本不使用回调,AFAIK。
pub fn send(&self, data: &[u8], flags: i32) -> Result<()> { ... }