2015-09-05 16 views
0

我想創建一個通過網絡發送和接收數據並將字節序列化/反序列化爲聲明類型的類型。爲此,我一直在std中使用PhantomData類型。但是,最近我遇到了一種情況,我想讓我的方法採用&mut self參數,而rustc不會編譯它。在下面的代碼中,當沒有可變引用時,所有東西都可以工作,但通過添加可變引用我得到<anon>:24:18: 24:21 error: vec does not live long enoughPhantomData和可變引用給出了一個「不夠長」的錯誤

我也嘗試使用PhantomData<*const T>類型,以免暗示所有權,但這並不奏效。擺脫結構中的PhantomData確實允許編譯代碼。

use std::io; 
use std::marker::PhantomData; 
struct Test<T> { 
    data: PhantomData<T>, 
} 

impl<T> Test<T> { 
    fn test(&mut self, _t: &T) -> Result<(), io::Error> { 
     Ok(()) 
    } 
} 

//impl<T> Test<T> { 
// fn test(&self, _t: &T) -> Result<(), io::Error> { 
//  Ok(()) 
// } 
//} 

fn main() { 
    let test = Test { 
     data: PhantomData, 
    }; 
    let vec = vec![1u8]; 
    let slice = &vec[..]; 
    let _res = test.test(&slice); 
} 

http://is.gd/okj55K

我不想test之前移動vec的創建。假設test是一個在進程開始時綁定的套接字,並且vec是一些正在傳遞的臨時數據。 任何有識之士將不勝感激!

編輯: 我想知道爲什麼這個工程與&self,而不是與&mut self。我正在尋找理解到底發生了什麼,以便我可以決定我的下一步應該是什麼。獲得這個特定代碼的工作是很棒的,但是對於rustc編譯器的想法的信息性解釋僅次於此。

+1

'&VEC [..]'應寫爲只是'&時下vec'。 – Veedrac

回答

2

這是糾正代碼:

fn main() { 
    let vec = vec![1u8]; 
    let mut test = Test { 
     data: PhantomData, 
    }; 
    let slice = &vec[..]; 
    let _res = test.test(&slice); 
} 

我剛搬到了vec創作。 然後test變量必須是可變的,因爲test方法需要這樣。註釋

的問題與您的代碼後

編輯是,當你調用test方法首次在Test型使用的通用型T推斷。在這種情況下,該類型是具有自己生命週期的切片。事實上,切片是一個藉口,所以它也有自己的一生。 在你的例子中,生命週期比變量生命週期短test,所以你有這個問題。

一種可能的方案是使用Vec類型是這樣的:

let mut test = Test { 
    data: PhantomData, 
}; 
let vec = vec![1u8]; 
let _res = test.test(&vec); 
+0

沒錯,那會讓這段代碼起作用,但我不想在創建'Test'結構之前創建Vec。我應該對此更加明確。想象一下'Test'結構體是一個在流程開始時創建的套接字,而'vec'則是正在傳遞的臨時數據。 – crhino

+0

@crhino我增加了另一個解決方案。 – eulerdisk

+0

如果我使用'Vec ',那麼這個方法可行,但我也想支持'&[u8]'的使用。我仍然不確定爲什麼slice需要更長的生命週期,然後是'test'變量。我的理解是切片只需要比'test.test(&slice)'更長的呼叫。無論如何,我正在努力達成這一目標。 – crhino

相關問題