2016-08-21 75 views
1

我想使用的CoerceUnsized功能:無法強迫嵌套尺寸無膠式使用CoerceUnsized

use std::rc::Rc; 
use std::borrow::Borrow; 

fn main() { 
    // Create (sized) i32 wrapped in an rc. 
    let a0: Rc<i32> = Rc::new(0i32); 
    // Coerce to (unsized) Borrow<i32> wrapped in an rc. 
    // Works fine in Beta and Nightly cause of CoerceUnsized. 
    let a1: Rc<Borrow<i32>> = a0.clone(); 

    // Create (sized) i32 in nested rcs. 
    let b0: Rc<Rc<i32>> = Rc::new(Rc::new(0i32)); 
    // Coerce to (unsized) Borrow<i32> in nested rcs. 
    // Does not compile in Stable, Beta or Nightly. 
    let b1: Rc<Rc<Borrow<i32>>> = b0.clone(); 

    println!("{}, {}", a1.borrow(), b1.borrow()); 
} 

Playground

但嵌套裹脅從Rc<Rc<i32>>Rc<Rc<Borrow<i32>>>不能編譯。

爲什麼CoerceUnsized不能遞歸工作?是否有任何解決方法,如顯式投射?

回答

4

轉換一個Rc<i32>Rc<Borrow<i32>>要求的只不過是添加旁邊Rc一個虛函數表指針多了,它不會影響由Rc管理的內存。另一方面,將Rc<Rc<i32>>轉換爲Rc<Rc<Borrow<i32>>將意味着將內存旁邊的虛擬指針存儲起來。這將需要修改(和擴大)由外部Rc管理的存儲器(即,它將有效地需要全新的分配)。你可以手動做到這一點,但它遠遠超出了強制的範圍。

+0

這是否與你無法強制'Vec >'到'&[&[T]]相同? - 中間商品需要更改尺寸? – Shepmaster

+0

好吧,你說得對,'Rc >'需要一個虛擬指針。但問題是,'Rc >'強制轉換爲'Rc >'不會導致vtable指針位於i32旁邊的堆上。在'&i32'轉換爲'&借方'的情況下,vtable指針保持在每個引用的旁邊。所以我猜想,vtable指針始終保持在最外層嵌套層次的旁邊。這將允許這種類型的轉換。我真的錯了嗎? – Pentagolo

+0

@Pentagolo否,vtable指針位於*最內層*嵌套層次旁邊(例如,最內層的可應用層級—'RefCell >'只是另一個未分類的類型,而不是可以存儲vtable指針的下一個引用) – delnan