我正在为Erlang NIF API做一些Rust FFI工作,我有这些:
ErlNifEnv *enif_alloc_env();
void enif_free_env(ErlNifEnv* env);
这个ErlNifEnv指针被传递给各种其他函数,但用户永远不会解析指针。此外,此指针不是线程安全的(在多个线程中使用将需要互斥锁)。这种类型的朴素Rust表示将是..
struct ErlNifEnv;
*mut ErlNifEnv;
但是,我认为我可以将这种类型视为具有“内部可变性”而导致......
struct ErlNifEnv;
*const ErlNifEnv;
我是否应该将此指针视为const,即使底层C代码将其视为非const?
答案 0 :(得分:3)
我个人认为你应该在对待Rust本身的引用时对待它们。当一个函数需要&mut
引用时,它很可能会实际更改该值,如果它需要&
,那么很自然地会期望该值不会被更改(当然,无视内心的可变性。)
C在继承和内部可变性之间没有区别,因此您可以根据C函数如何使用此值来选择使用*mut
或*const
的内容。事实上,在正确编写的C API中,这种区别将以const
限定符的形式出现。因此,如果有任何想要改变值的函数,请使用*mut
。如果没有这样的函数(例如,这是一个只创建一次的不可变结构),请使用*const
。当然,这适用于您要在包装器中存储的类型 - 在FFI函数签名中,您应始终镜像C API签名。