我想将a转换Vec<T>
为Vec<U>
whereT
是某种原始类型,并且U
是T
:的新类型struct U(T)
。
我尝试过这样的事情:
struct Foo(u32);
fn do_something_using_foo(buffer: &mut Vec<Foo>) {}
fn main() {
let buffer: Vec<u32> = vec![0; 100];
do_something_using_foo(&mut buffer as Vec<Foo>);
}
我不想复制向量,我想将u32
字段包装在newtype中Foo
。
这给出了错误:
error[E0308]: mismatched types
--> main.rs:8:28
|
8 | do_something_using_foo(&mut buffer as Vec<Foo>);
| ^^^^^^^^^^^^^^^^^^^^^^^ expected mutable reference, found struct `std::vec::Vec`
|
= note: expected type `&mut std::vec::Vec<Foo>`
found type `std::vec::Vec<Foo>`
= help: try with `&mut &mut buffer as Vec<Foo>`
error: non-scalar cast: `&mut std::vec::Vec<u32>` as `std::vec::Vec<Foo>`
--> main.rs:8:28
|
8 | do_something_using_foo(&mut buffer as Vec<Foo>);
| ^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error(s)
您无法在安全的Rust中更改值的类型。不能保证这两种类型将具有相同的大小或相同的语义。
这适用于单个值(T
-> U
)以及合计值(Vec<T>
-> Vec<U>
,HashMap<K1, V1>
-> HashMap<K2, V2>
)。注意,聚合值实际上只是“单个”值的一种特殊情况。
最好的办法是创建一个新向量:
let buffer2 = buffer.into_iter().map(Foo).collect();
你也可以调整do_something_using_foo
采取一个共同的泛型类型,无论Foo
和u32
实施:
use std::borrow::{Borrow, BorrowMut};
#[derive(Debug, Clone)]
struct Foo(u32);
impl Borrow<u32> for Foo {
fn borrow(&self) -> &u32 {
&self.0
}
}
impl BorrowMut<u32> for Foo {
fn borrow_mut(&mut self) -> &mut u32 {
&mut self.0
}
}
fn do_something_using_foo<T>(buffer: &mut [T])
where
T: BorrowMut<u32>,
{
}
fn main() {
let mut buffer_u32 = vec![0u32; 100];
let mut buffer_foo = vec![Foo(0); 100];
do_something_using_foo(&mut buffer_u32);
do_something_using_foo(&mut buffer_foo);
}
在不安全的Rust中,从技术上讲,这是可能的-您可以随意射击自己的脚。
std::mem::transmute
如果您知道自己在做什么,可以使用类似的方法。
然而,这是不确定的行为,以使用transmute
与Vec
作为的表现Vec
没有定义。相反,请参阅Sven Marnach的答案。
也可以看看:
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句