This question already has answers here:
Is it possible to create a RefCell<Any>?
(2 个回答)
1年前关闭。
在 Rust 1.36 中,编译如下:
但是这个失败了,错误是:
谁能解释为什么行为不同?
这里的原因是
碰巧的是,
其他(智能)指针也可以在这里工作。
(2 个回答)
1年前关闭。
在 Rust 1.36 中,编译如下:
let arr = [0 as u8; 30];
let buf: Box<[u8]> = Box::new(arr);
但是这个失败了,错误是:
expected slice, found array of 30 elements
指的是带下划线的代码:let arr = [0 as u8; 30];
let buf: RefCell<[u8]> = RefCell::new(arr);
^^^^^^^^^^^^^^^^^
谁能解释为什么行为不同?
RefCell
和 Box
都将 T 约束为 <T: ?Sized>
。 最佳答案
Box<T>
实现了 the trait CoerceUnsized<U>
,它允许在 Box<T>
实现 the trait Box<U>
时从 T
强制转换为 Unsize<U>
。直观地说,如果 T
是 Unsize<U>
的“未调整大小”版本,则 U
实现了 T
。例如,当 [T; N]
实现 Unsize<[T]>
时,T
实现 Unsize<dyn Trait>
和 T
实现 Trait
。
impl<T, U> CoerceUnsized<Box<U>> for Box<T> where
T: Unsize<U> + ?Sized,
U: ?Sized,
RefCell<T>
也实现了 CoerceUnsized<U>
,但有一个更有限的实现。如果 RefCell<T>
已经可以被强制转换为 RefCell<U>
,则它只能执行从 T
到 U
的强制转换,其中不包括 T: Unsize<U>
。impl<T, U> CoerceUnsized<RefCell<U>> for RefCell<T> where
T: CoerceUnsized<U>,
这里的原因是
CoerceUnsized<U>
后面的强制转换应该总是在一个指针后面。这适用于 Box<T>
,但不适用于 RefCell<T>
。 RefCell<T>
尽管被称为 Ref Cell,但实际上直接保存其数据。 RefCell<T>
有字段 value: UnsafeCell<T>
, UnsafeCell<T>
只有一个字段 value: T
。这里没有间接进行。碰巧的是,
Unsize<U>
的规则确实允许 RefCell<T>: Unsize<RefCell<U>>
当 T: Unsize<U>
时,所以如果我们隐藏在指针后面,我们可以在它们之间进行强制。use std::cell::RefCell;
fn main() {
let _: &mut RefCell<[u8]> = &mut RefCell::new([0; 30]);
}
其他(智能)指针也可以在这里工作。
Box<T>
、 Rc<T>
等。 (playground link)关于rust - Box<T> 和 RefCell<T> 构造函数之间的行为差异,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57563768/
10-12 06:54