extern crate core;
use core::ops::{Deref, DerefMut};
struct MutPtr<'a,T>{
ptr: *mut T
}
impl<'a,T> MutPtr<'a,T>{
fn new<'b>(value: &'b mut T) -> MutPtr<'b,T>{
MutPtr{ptr: value}
}
}
impl<'a,T> Deref for MutPtr<'a,T>{
type Target = T;
fn deref(&self) -> &T{
unsafe{
&(*self.ptr)
}
}
}
impl<'a,T> DerefMut for MutPtr<'a,T>{
fn deref_mut(&mut self) -> &mut T{
unsafe{
&mut (*self.ptr)
}
}
}
struct Bar{
v: i32
}
fn err<'a>() -> MutPtr<'a,Bar>{
let mut b = Bar{v:42};
MutPtr::new(&mut b) // Shouldn't this throw an error?
}
fn main(){
let mut b = Bar{v:42};
let mut ptr_b = MutPtr::new(&mut b);
let mut ptr_b1 = MutPtr::new(&mut b);
ptr_b.v = 10;
println!("{}",b.v);
ptr_b1.v = 21;
println!("{}",b.v);
}
此代码块导致一些混淆。
fn err<'a>() -> MutPtr<'a,Bar>{
let mut b = Bar{v:42};
MutPtr::new(&mut b) // Shouldn't this throw an error?
}
为什么要编译?
当我打电话
MutPtr::new(&mut b)
不应该有b的寿命吗?我期望编译错误,因为生命周期'a比MutPtr的生命周期长'b,Bar&gt;
答案 0 :(得分:4)
我认为您要找的是core::marker::ContravariantLifetime
(也可在std::marker::ContravariantLifetime
中找到)
发生的事情是编译器没有为指针变量分配任何生命周期,因此全局结构的生命周期不受内部的限制(在你的情况下应该是这样)
这样做的方法是在结构中添加一个标记ContravariantLifetime
,告诉编译器如果推断的生命周期长于标记,那么编译器会将整个结构的生命周期缩短到标记中的生命周期。在标记中。
所以最后你的结构应该是这样的:
struct MutPtr<'a,T>{
ptr: *mut T,
marker: ContravariantLifetime<'a>,
}
impl<'a,T> MutPtr<'a,T>{
fn new<'b>(value: &'b mut T) -> MutPtr<'b,T>{
MutPtr{ptr: value, marker: ContravariantLifetime::<'b>}
}
}
这样您就会得到预期的错误b does not live long enough