更具体地讲,为什么没有 Arc<T>实现from_raw与动态调整T,同时Box<T> 呢?
use std::sync::Arc;
fn main() {
let x = vec![1, 2, 3].into_boxed_slice();
let y = Box::into_raw(x);
let z = unsafe { Arc::from_raw(y) }; // ERROR
}
Run Code Online (Sandbox Code Playgroud)
(玩)
正如在注释中指出的那样,Arc::from_raw 必须使用指针来自Arc::into_raw,所以上面的例子没有意义.我原来的问题(是否有可能Arc<[T]>从a 创建Vec<T>)仍然存在:这是可能的,如果没有,为什么?
从Rust 1.21.0开始,您可以这样做:
let thing: Arc<[i32]> = vec![1, 2, 3].into();
Run Code Online (Sandbox Code Playgroud)
这是由RFC 1845启用的:
另外:
From<Vec<T>> for Rc<[T]>和From<Box<T: ?Sized>> for Rc<T>将被添加.还将添加相同的API
Arc.
在内部,这使用了一个被调用的方法copy_from_slice,因此Vec不重用它的分配.有关详细信息,请查看DK.的答案.
没有.
首先,正如评论中已经提到的那样,你不能像那样肆无忌惮地抛出原始指针.引用以下文档Arc::from_raw:
必须先通过调用a返回原始指针
Arc::into_raw.
您必须在使用unsafe方法时随时阅读文档.
其次,你想要的转换是不可能的. Vec<T>→ Box<[T]>有效,因为在内部Vec<T>实际上是(Box<[T]>, usize)一对.因此,所有方法都可以让您访问该内部Box<[T]>指针[1]. Arc<[T]>但是,它与a在物理上不兼容Box<[T]>,因为它必须包含引用计数.被指向的东西Arc<T>具有与被指向的东西不同的大小和布局Box<T>.
你可以从得到的唯一方法Vec<T>,以Arc<[T]>将重新分配向量的引用计数分配的内容...这我不知道有任何办法的事情.我不相信它有任何特殊原因无法实施,它只是没有[2].
所有这一切,我认为不能使用动态大小的类型Arc::into_raw/ Arc::from_raw是一个错误.Arc使用动态大小的类型来获取s 肯定是可能的......尽管只能通过从指针转换为固定大小的类型.
[1]:不完全. Vec<T>它实际上没有Box<[T]>内部,但它有一些兼容的东西.它还必须缩小切片以不包含未初始化的元素.
[2]:总的来说,Rust并不能很好地支持动态调整大小的东西.特别是这个漏洞的部分原因可能是Box<T> 也不能直接分配数组,这可能是因为Vec<T>存在,因为Vec<T>曾经是语言本身的一部分,为什么要Box在Vec已经存在时添加数组分配? "那为什么不ArcVec<T>呢?" 因为共享所有权,你永远无法构建一个.
| 归档时间: |
|
| 查看次数: |
636 次 |
| 最近记录: |