【发布时间】:2016-05-11 20:08:11
【问题描述】:
我对一个 C 库做了一个封装,它创建了一个必须明确关闭的设备。
编写原始 FFI 函数很容易,但是如何在更高级别的包装器中使其符合人体工程学 Rust?
具体来说,我是否应该使用 RAII 样式并仅使用 Drop 来确保在超出范围时调用 close,而不是将 close() 方法暴露给调用者? Rust 中哪种方式最惯用?
基本上有3个选项:
- 需要与 C 库相同的
close()调用的瘦包装器; - 没有暴露的
close(),只有Drop实现的RAII 样式; - C#
dispose()风格的实现,跟踪关闭状态并允许两种关闭形式。
最后一个表格是这样的:
pub enum NativeDevice {} // Opaque pointer to C struct
fn ffi_open_native_device() -> *mut NativeDevice { unimplemented!() }
fn ffi_close_native_device(_: *mut NativeDevice) {}
fn ffi_foo(_: *mut NativeDevice, _: u32) -> u32 { unimplemented!() }
pub struct Device {
native_device: *mut NativeDevice,
closed: bool,
}
impl Device {
pub fn new() -> Device {
Device {
native_device: ffi_open_native_device(),
closed: false,
}
}
pub fn foo(&self, arg: u32) -> u32 {
ffi_foo(self.native_device, arg)
}
pub fn close(&mut self) {
if !self.closed {
ffi_close_native_device(self.native_device);
self.closed = true;
}
}
}
impl Drop for Device {
fn drop(&mut self) {
self.close();
}
}
【问题讨论】:
-
选项编号 2。我从未见过选项 1 或 3 用于 rust。在您的示例中,当
close被多次调用时会发生什么? -
很好看,如果关闭当然应该在 close() 方法中,而不是在 drop() 中。已编辑。
标签: rust