为什么*mut i8用于ncurses-rs中的WINDOW类型?

mjh*_*hoy 0 types rust

在ncurses-rs包中给出这个定义:

pub type WINDOW = *mut i8;
Run Code Online (Sandbox Code Playgroud)

一个用法WINDOW:

pub fn newwin(_:c_int,_:c_int,_:c_int,_:c_int) -> WINDOW;
Run Code Online (Sandbox Code Playgroud)

和实施,在ncurses的C库(1,2,3):

// 1:
typedef struct _win_st WINDOW;
// 2:
struct _win_st { 
    /* lots of fields... */
};
// 3: 
(WINDOW *) newwin (int,int,int,int);
Run Code Online (Sandbox Code Playgroud)

为什么是这种类型的WINDOW *mut i8

我正在读它作为指向C的指针char,这显然是不正确的.i8如果你没有在Rust中实现C结构,那么最好简单地说一个指针是类型的吗?这根本不重要吗?

She*_*ter 6

除非该项目的作者碰巧过去,否则你将无法得到权威的答案.

正如mcarton指出的那样,你通常会void *在C中找到一个表示对不透明结构的引用.作者可以轻松完成

pub type WINDOW = *mut c_void;
Run Code Online (Sandbox Code Playgroud)

通过此更改,代码仍然可以编译.

但是,有一个更好的选择.正如文件所说:

要在Rust中执行此操作,让我们创建自己的opaque类型enum:

pub enum Foo {}
pub enum Bar {}

extern "C" {
    pub fn foo(arg: *mut Foo);
    pub fn bar(arg: *mut Bar);
}
Run Code Online (Sandbox Code Playgroud)

通过使用enum没有变体的,我们创建了一个我们无法实例化的opaque类型,因为它没有变体.但是因为我们FooBar 类型不同,我们将在它们之间获得类型安全性,所以我们不会意外地将指针传递Foobar().

在这种情况下,它可能看起来像:

pub enum Window {}
pub type WINDOW = *mut Window;
Run Code Online (Sandbox Code Playgroud)

同样,图书馆仍然会编译这一变化.