Rust中,*const T和*mut T的区别是什么?

*const T*mut T的区别是什么?为什么Unique的实现中,是使用*const T而不是使用*mut T

答案:

(1)解引用后的区别,*const T指针解引用对应&T,*mut T解引用对应&mut T;

(2)在安全的代码中,可以将*const T转换为*mut T,因为对于解引用之前,都是原始裸指针,原始裸指针之间转换时可以的;

(3)为什么Unique的实现中,使用*const T而不是*mut T,其原因如下:

  • 根据Rust的规则,只有真正拥有变量或者是可变引用的情况下,才能修改变量,对于指针我们可以同样的理解;
  • 因此,在满足安全的情况下,要求Unique是协变的;
  • 根据我们在死灵书3.8节子类型和变性中的内容,*const T是对T是协变的。

补充知识:

  • *const T对于T是协变的;
  • *mut T对于T是不变的。
C++ 的 `shared_ptr` 和 Rust 的 `Rc`、`Arc` 都是智能指针,可以用于内存管理,但是由于语言不同,它们在底层实现上有很大的差异,因此在 C++ 和 Rust 之间交互时需要特别注意。 要在 C++ 和 Rust 之间交互 `shared_ptr`,可以使用 `cxx` 库进行绑定。具体来说,我们需要在 C++ 将 `shared_ptr` 转换为 `void*`,然后将其传递给 RustRust 再将 `void*` 转换为 `Rc` 或者 `Arc`。 以下是一个简单的例子,演示了如何在 C++ 和 Rust 之间交互 `shared_ptr`: C++ 代码: ```cpp #include <memory> #include <iostream> #include <cxxbridge/cxx.h> struct Foo { int x; Foo(int x) : x(x) {} void hello() { std::cout << "Hello from Foo(" << x << ")!\n"; } }; std::shared_ptr<Foo> make_foo(int x) { return std::make_shared<Foo>(x); } void use_foo(std::shared_ptr<Foo> ptr) { ptr->hello(); } void* get_raw_ptr(std::shared_ptr<Foo> ptr) { return (void*) ptr.get(); } CXX_EXPORT void cxxbridge_demo_run() { auto foo = make_foo(42); use_foo(foo); void* raw_ptr = get_raw_ptr(foo); // 将 void* 指针传递给 Rust rust_use_shared_ptr(raw_ptr); } ``` Rust 代码: ```rust use std::rc::Rc; use std::cell::RefCell; use std::ffi::c_void; struct Foo { x: i32, } impl Foo { fn new(x: i32) -> Self { Self { x } } fn hello(&self) { println!("Hello from Foo({})!", self.x); } } // 用于从 void* 指针构造 Rc 智能指针 fn from_raw_ptr<T>(ptr: *mut c_void) -> Rc<T> { unsafe { Rc::from_raw(ptr as *const T as *mut T) } } // 用于从 Rc 智能指针构造 void* 指针 fn to_raw_ptr<T>(rc: Rc<T>) -> *mut c_void { Rc::into_raw(rc) as *mut c_void } // 用于接收 C++ 传递的 shared_ptr 指针 #[no_mangle] extern "C" fn rust_use_shared_ptr(ptr: *mut c_void) { let rc = from_raw_ptr::<Foo>(ptr); rc.hello(); } fn main() { let foo = Rc::new(Foo::new(42)); let ptr = to_raw_ptr(foo.clone()); unsafe { // 将 Rc 智能指针指向的内存传递给 C++ cpp_use_shared_ptr(ptr); } } // 用于调用 C++ 的函数,并传递 Rc 智能指针指向的内存 #[link(name = "cxxbridge_demo")] extern "C" { fn cpp_use_shared_ptr(ptr: *mut c_void); } ``` 在这个例子,我们定义了一个 `Foo` 类和两个函数 `make_foo` 和 `use_foo`,它们分别用于创建 `shared_ptr` 类型的对象和使用 `shared_ptr` 类型的对象。我们还定义了一个 `get_raw_ptr` 函数,它可以将 `shared_ptr` 转换为 `void*`,方便在 C++ 和 Rust 之间传递。 在 Rust 代码,我们定义了一个 `Foo` 结构体,并实现了 `from_raw_ptr` 和 `to_raw_ptr` 函数,用于将 `void*` 指针和 `Rc` 智能指针进行转换。在 `main` 函数,我们创建一个 `Rc` 智能指针,然后将其指向的内存传递给 C++ 的 `cpp_use_shared_ptr` 函数。在 `rust_use_shared_ptr` 函数,我们将 `void*` 指针转换为 `Rc` 智能指针,并使用其调用 `hello` 方法。 最后,我们需要使用 `cxx` 将 C++ 和 Rust 代码进行绑定。具体来说,我们需要在 C++ 代码使用 `CXX_EXPORT` 宏将 `cxxbridge_demo_run` 函数导出为 C 风格的函数,然后在 Rust 代码使用 `extern "C"` 关键字声明该函数。同时,我们还需要在 Rust 代码使用 `#[link(name = "cxxbridge_demo")]` 注解来链接 C++ 库。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值