【问题标题】:When should I use `&mut self` vs. `&self` in Rust bindings for a C library?我什么时候应该在 C 库的 Rust 绑定中使用 `&mut self` 与 `&self`?
【发布时间】:2016-11-18 15:12:16
【问题描述】:

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

一点背景知识:libzmq 提供了套接字“对象”,它有一个类似于 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 标准库方法使用 &amp;mut self,例如std::io::Write::write(),由 std::net::TcpStream 实现。另一方面,std::net::UdpStream::write() 只需要&amp;self。我的猜测是使用 &amp;mut self 只是因为它是 Write 特征的实现,而后者(我猜)使用 &amp;mut self 来不限制特征的实现。

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

【问题讨论】:

标签: rust ffi


【解决方案1】:

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

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

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

【讨论】:

  • 我应该补充一点,所讨论的套接字选项不是线程安全的,但是如果绑定没有实现Sync 线程,则类型系统应该禁止跨线程共享,对吧?而且 libzmq C API 根本不使用回调,AFAIK。
猜你喜欢
  • 2012-05-22
  • 1970-01-01
  • 2011-11-07
  • 1970-01-01
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多