我在试着理解借阅支票。我有一个有签名的函数
fn SerializeChar(&mut self, value: &mut u8)我想从u8和i8获得数据,因为我不关心标牌:
let mut test: i8 = 0;
thing.SerializeChar(&mut test); //Error: &mut u8 expected很好,但我该怎么演呢?
&mut (test as u8)不是一回事。是否有任何安全或不安全的方法可以通过测试作为SerializeChar的参数,类似于C++中的强制转换?而且,当我这样做时,我也不想破坏test,因为我仍然需要test,并且仍然希望它是一个i8,而不是一个u8。
我不是想复制这个价值。我想要test的地址,因为SerializeChar中的数据是可变的,需要修改输入的任何内容。用C++术语来说,我不想要char,我想要一个*char,因为我需要修改内存中的8位。我有可能可以做两个不同版本的SerializeChar,但在此之前,我想知道是否真的可以做一些类似*u8(test)的事情,而借用检查器是可以的。
发布于 2019-03-15 12:31:12
第一件事,这与借阅检查无关。被告知一种类型与另一种类型不同是类型检查器的权限。
是否有任何安全或不安全的方法将
test作为参数传递给SerializeChar,类似于C++中的强制转换?
通过原始指针
按以下顺序转换:
&mut i8*mut i8*mut u8&mut u8fn serialize_char(value: &mut u8) {
*value = std::u8::MAX
}
fn main() {
let mut test: i8 = 0;
serialize_char(unsafe { &mut *(&mut test as *mut i8 as *mut u8) });
println!("{}", test); // -1
}另请参阅:
transmute
使用as应该永远是您的第一次尝试,但也有transmute的大锤子。与更简单的as转换序列相比,这允许您做各种各样的坏事,并且在有其他选择时不受欢迎:
use std::mem;
fn serialize_char(value: &mut u8) {
*value = std::u8::MAX
}
fn main() {
let mut test: i8 = 0;
serialize_char(unsafe { mem::transmute(&mut test) });
println!("{}", test); // -1
}另请参阅:
安全性
所有通过as进行的数据转换都是安全的,尽管它们可能会产生虚假或意外的数据。
从*mut u8转换到&mut u8或使用transmute是不安全的,因为程序员必须确保:
我们知道引用是有效的:仍然只有一个可变的引用,它指向活数据。
u8和i8对于任何8位位模式都是有效的,尽管语义值可能会改变,如u8::MAX变成-1所示。
尽管如此,这并不意味着没有更好的方法来完成你的目标。作为兰尼,您可以为有趣的类型创建一个特性,并隐藏实现内部的不安全代码。这使您的用户可以避免不安全。
您还可以使用宏来创建多个类似的函数,而不让它们实际上是相同的。
也许还有更高层次的方法来解决你真正的问题。为什么你必须在这里对数据进行变异?这似乎是非常不寻常的序列化。
发布于 2019-03-15 12:37:55
你不能安全地这么做。一旦您有了&mut对u8的引用,使用它的代码只能将其视为一个u8,您需要一些不安全的代码来进行转换。
as可以处理原始数值,因为它在内存中复制数据,并且可以处理此时的任何转换。这将不适用于引用,因为它无法更改原始值。
如果您绝对不能更改thing.serialize_char的签名,并且不能更改test变量的类型,那么解决方法是使用另一个变量,然后更新原始变量:
let mut test: i8 = 0;
let mut test_u8 = test as u8;
thing.serialize_char(&mut test_u8);
test = test_u8 as i8;如果serialize_char需要比函数调用更长的引用时间,这是行不通的--但是如果是这样的话,借用检查器很快就会通知您!
发布于 2019-03-15 10:02:16
锈蚀中的特征可以是通用的,因此您可以定义具有以下签名的特征:
trait SerializeChar<T> {
fn serialize_char(&mut self, value: &mut T);
}然后用T = u8和T = i8为您的结构实现它:
struct Thing {}
impl SerializeChar<u8> for Thing {
fn serialize_char(&mut self, value: &mut u8) { *value = 55; }
}
impl SerializeChar<i8> for Thing {
fn serialize_char(&mut self, value: &mut i8) { *value = 56; }
}测试:
fn main() {
let mut a = 0u8;
let mut b = 0i8;
let mut thing = Thing{};
thing.serialize_char(&mut a);
thing.serialize_char(&mut b);
dbg!(a);
dbg!(b);
}https://stackoverflow.com/questions/55176192
复制相似问题