如何将动态字节字符串插入向量中?

How do I insert a dynamic byte string into a vector?

我需要创建数据包发送到服务器。为此,我将 vector 与 byteorder 板条箱一起使用。当我尝试附加字符串时,Rust 编译器告诉我使用了不安全的函数并给我一个错误。

use byteorder::{LittleEndian, WriteBytesExt};

fn main () {
    let login = "test";
    let packet_length = 30 + (login.len() as i16);

    let mut packet = Vec::new();
    packet.write_u8(0x00);
    packet.write_i16::<LittleEndian>(packet_length);
    packet.append(&mut Vec::from(String::from("game name ").as_bytes_mut()));

    // ... rest code
}

错误是:

packet.append(&mut Vec::from(String::from("game name ").as_bytes_mut()));
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function

这是重现的游乐场:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=381c6d14660d47beaece15d068b3dc6a

将一些字符串作为字节插入向量的正确方法是什么?

调用的不安全函数是 as_bytes_mut()。这将创建一个可变引用,可以 独占 访问表示字符串的字节,从而允许您修改它们。在这种情况下你真的不需要可变引用,as_bytes() 就足够了。

不过,还有一种更惯用的方法。 Vec<u8> 也可以用作写入器(它实现了 std::io::Write),因此您可以使用它的方法之一,甚至 write! 宏,在其上写入编码文本。

use std::io::Write;
use byteorder::{LittleEndian, WriteBytesExt};

fn main () -> Result<(), std::io::Error> {
    let login = "test";
    let packet_length = 30 + (login.len() as i16);
    let mut packet = Vec::new();
    packet.write_u8(0x00)?;
    packet.write_i16::<LittleEndian>(packet_length)?;
    let game_name = String::from("game name");
    write!(packet, "{} ", game_name)?;

    Ok(())
}

Playground

另请参阅:

您可以在 Vec 上使用 .extend() 并传入 String 的字节表示:

use byteorder::{LittleEndian, WriteBytesExt};

fn main() {
    let login = "test";
    let packet_length = 30 + (login.len() as i16);
    let mut packet = Vec::new();
    packet.write_u8(0x00);
    packet.write_i16::<LittleEndian>(packet_length);
    let string = String::from("game name ");
    packet.extend(string.as_bytes());
}

Playground