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>のライフタイムよりも長いため、コンパイルエラーが予想されました。
私はあなたが探しているのは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
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加