use std::marker;
use std::ops;
pub struct Shared<'r, T: 'r> {
data: *mut T,
_pd: marker::PhantomData<&'r T>,
}
impl<'r, T> Shared<'r, T> {
pub fn new(value: T) -> Shared<'r, T> {
let boxed = Box::new(value);
Shared {
data: Box::into_raw(boxed),
_pd: marker::PhantomData,
}
}
pub fn as_ref(&self) -> SharedRef<'r, T> {
SharedRef {
data: self.data,
_pd: marker::PhantomData,
}
}
}
impl<'r, T> ops::Deref for Shared<'r, T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.data }
}
}
pub struct SharedRef<'r, T: 'r> {
data: *mut T,
_pd: marker::PhantomData<&'r T>,
}
impl<'r, T> ops::Deref for SharedRef<'r, T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.data }
}
}
impl<'r, T> Drop for Shared<'r, T> {
fn drop(&mut self) {
unsafe {
Box::from_raw(self.data);
}
}
}
fn main() {
let s = Shared::new(42);
let s_ref = s.as_ref();
{
let s1 = s;
}
// lifetime should end here
println!("{}", *s_ref);
}
我要表达的是
Box
和Arc
之间的混合。唯一拥有的指针,也能够给出引用。问题是,即使当前有不可变的借用,我也希望能够移动
Shared
。在这种情况下,它应该是合法的,因为它是堆分配的。问题是我不知道该如何表达。
fn main() {
let s = Shared::new(42);
let s_ref = s.as_ref();
{
let s1 = s;
}
// lifetime should end here
println!("{}", *s_ref);
}
在这里,我将
s
移入生存期比以前短的范围。但是现在我将s
移到s1
之后,就不再可以访问s_ref
了。因此,我想说的是,如果生存期没有变短,可以移动Shared
。可以用Rust表示吗?
最佳答案
Rust允许您移出Shared
的原因是您尚未将返回的SharedRef
的生命周期与其绑定(bind):
pub fn as_ref(&self) -> SharedRef<'r, T> {
SharedRef {
data: self.data,
_pd: marker::PhantomData,
}
}
注释
&self
可解决以下问题:pub fn as_ref(&'r self) -> SharedRef<'r, T> { .. }
我目前的理解是,这里的主要区别在于,这意味着
SharedRef
的生存期现在与self
的借用生存期匹配,从而使借用仍然有效。实际上,它的生存期('r
)不必与Shared
中的生存期相同;它为借/还款提供了新的生命周期:pub fn as_ref<'b>(&'b self) -> SharedRef<'b, T> { .. }
这也不允许移动。
至于问题的奖励部分,您想允许它一直移动到生命周期足够长的东西,我认为答案是否定的。我知道完全停止移动任何东西的唯一方法就是借用它,这将停止任何移动。
关于rust - 即使是一成不变的借贷,也有可能搬家吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39056626/