2016-06-13 49 views
2

考慮以下兩個結構:是否有可能通過引用返回結構的一部分?

pub struct BitVector<S: BitStorage> { 
    data: Vec<S>, 
    capacity: usize, 
    storage_size: usize 
} 

pub struct BitSlice<'a, S: BitStorage> { 
    data: &'a [S], 
    storage_size: usize 
} 

哪裏BitStorage實際上是被限制在所有無符號整數(U8,U16,U32,U64,USIZE)類型。

如何實施Deref特質? (BitVector<S> derefs到BitSlice<S>類似於如何Vec<S> derefs至&[S]

我曾嘗試以下(請注意,它不會由於與壽命問題的編譯,但更重要的是,因爲我嘗試在堆棧上返回值參考):

impl<'b, S: BitStorage> Deref for BitVector<S> { 
    type Target = BitSlice<'b, S>; 

    fn deref<'a>(&'a self) -> &'a BitSlice<'b, S> { 
     let slice = BitSlice { 
      data: self.data, 
      storage_size: self.storage_size, 
     }; 
     &slice 
    } 
} 

我知道可以通過引用返回一個結構的領域,因此,例如,我可以在Deref性狀返回&Vec<S>&usize,但有可能返回一個BitSlice注意到我基本上擁有中的所有數據210已經作爲Vec<S>可以轉換成&[S]storage_size已經在那裏?

我會認爲這是可能的,如果我可以使用這兩個值創建一個結構,並以某種方式告訴編譯器忽略這一事實,即它是在堆棧上創建的結構,而不是使用現有的值,但我有不知道如何。

回答

2

Deref需要返回參考。一個參考總是指向一些現有的內存,並且任何局部變量都不會存在足夠長的時間。從理論上講,您可以在deref中創建一個新對象,並返回對它的引用,但我知道的所有內容都會導致內存泄漏。讓我們忽略這些技術問題,只是說這根本不可能。

現在呢?你將不得不改變你的API。 Vec可以實現Deref,因爲它破壞到[T],而不是&[T]或類似的東西。您可能使用相同的策略獲得成功:使BitSlice<S>爲僅包含切片[S]的未分類類型,以便返回類型爲&'a BitSlice<S>。這假定storage_size成員是不需要的。但看起來這是指邏輯有效的位數(即,可以在不擴展位向量的情況下訪問),如果是這樣的話,那似乎是不可避免的。

另一種替代方法當然是不執行Deref。不方便,但如果您的切片數據類型距實際切片太遠,則可能是唯一的選擇。

RFC PR #1524建議自定義動態大小的類型,那麼你可以有一個BitSlice<S>類型,就像一個切片,但可以有其他內容,如storage_size。然而,這還不存在,如果它永遠不會確定的話。

然而BitVector上的capacity成員似乎毫無意義。這不僅僅是sizeof S * 8

+0

你的想法是正確的,即'storage_size'不是必需的,它只是'std :: mem :: size_of :: ()* 8',但是恐怕需要'capacity',因爲你可以分配位向量不是後備存儲的乘積,即。後備存儲是u32,你想分配50位,但是如果這樣做可以解除壓縮的作用,強制分配多個後備存儲器可能是合理的 – skiwi

相關問題