如何引用不安全块中使用的变量?

时间:2016-03-16 15:54:11

标签: rust

我正在尝试从套接字读取4个字节,然后将这些字节转换为单个u32。

let mut length: u32 = 0;

// Transmute 4 byte array into u32
unsafe {
    let length = mem::transmute::<[u8; 4], u32>(buf); // buf is the 4 item array of u8 that the socket was read into
    println!("1: {:}", length);
}

println!("Length: {:}", length);

但是,一旦在不安全块之外,长度的原始值为0。我怎么能绕过这个?

2 个答案:

答案 0 :(得分:8)

在内部区块中,您未通过定义新的length绑定为外部length绑定you are shadowing it分配新值。

我相信在一个像这样的简单代码片段中(外部可变变量不被重新分配)通常应该有一个编译器警告:

  

警告:变量不需要是可变的

在任何情况下,由于您已声明了外部可变绑定,因此重新分配原始变量所需要做的就是删除let块中的关键字unsafe

另外,正如评论中所指出的那样:

  • 没有必要使用值初始化此特定绑定,因为该值在使用之前总是会被替换。
  • 如果您以后没有真正重新分配该变量(在您的问题中未显示的代码中),那么它甚至不需要是可变的。可变性不会强迫您在源代码中声明变量时初始化变量。

所以这应该足够了:

let length: u32; // or mut  
unsafe {
    length = mem::transmute::<[u8; 4], u32>(buf);
    println!("1: {:}", length);
}

println!("Length: {:}", length);

答案 1 :(得分:5)

注意(除了Theodoros&#39;回答)不安全的块是一个表达式,所以你可以这样做:

let buf = [1u8, 2, 3, 4];

// Transmute 4 byte array into u32
let length = unsafe {
    let length = std::mem::transmute::<[u8; 4], u32>(buf); // buf is the 4 item array of u8 that the socket was read into
    println!("1: {:}", length);
    length
};

println!("Length: {:}", length);

或简而言之:

let length = unsafe {std::mem::transmute::<[u8; 4], u32>(buf)};