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

rot*_*tty 3 ffi rust

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

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

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

int zmq_send (void *socket, void *buf, size_t len, int flags);
Run Code Online (Sandbox Code Playgroud)

我认为它可以(并且应该)使用不可变的自我来暴露,即:

pub fn send(&self, data: &[u8], flags: i32) -> Result<()> { ... }
Run Code Online (Sandbox Code Playgroud)

然而,可比较的Rust标准库方法使用&mut self,例如std::io::Write::write(),如实现的那样std::net::TcpStream.另一方面,std::net::UdpStream::write()只需要&self.我的猜测是&mut self因为它是特征的实现而被使用Write,而这反过来(我猜)用于&mut self不限制特征的实现.

我希望有人可以在这里备份或反驳我的推测 - 我在书或Nomicon中找不到任何关于该主题的具体内容.

Chr*_*son 5

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

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

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