【问题标题】:Rust - padded array of bytes from strRust - 来自 str 的填充字节数组
【发布时间】:2021-03-20 19:40:07
【问题描述】:

这种锈完全符合我的要求,但我不会做太多锈,我觉得这可以做得更好 - 就像可能在一行中一样。任何人都可以提示更“生锈惯用”的方式吗?

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1f139ccf6e8f88dbe92f1f1e4d7a487a

fn fill_from_str(bytes: &mut [u8], s: &str) {
    let mut i=0;
    for b in s.as_bytes() {
        bytes[i] = *b;
        i=i+1;
    }
} 

fn main() {
    let mut bytes: [u8; 10] = [0; 10];
    fill_from_str(&mut bytes,"hello");
    println!("{:?}",bytes);
}

【问题讨论】:

  • 请注意,如果字符串太长,您提供的示例代码将溢出缓冲区,如果最后一个字符是多字节编码但不完整,则会在代码点之间切入。
  • 没关系,输入已检查。

标签: rust


【解决方案1】:

这可以通过为&mut [u8] 实现的std::io::Write 非常简洁地完成:

use std::io::Write;

fn fill_from_str(mut bytes: &mut [u8], s: &str) {
    bytes.write(s.as_bytes()).unwrap();
} 

fn main() {
    let mut bytes: [u8; 10] = [0; 10];
    fill_from_str(&mut bytes, "hello");
    println!("{:?}", bytes);
}
[104, 101, 108, 108, 111, 0, 0, 0, 0, 0]

【讨论】:

    【解决方案2】:

    有一个更好的方法来做到这一点:copy_from_slice 方法。如果切片和字符串的长度相同,这是一个单行:

    fn copy_from_str(dest:&mut[u8], src:&str){
        dest.copy_from_slice(src.as_bytes());
    }
    

    copy_from_slice 方法也只是对memcpy 的一次调用,因此它比您的版本更快。如果您想支持不同的尺寸,则需要更多代码:

    fn copy_from_str(dest:&mut [u8],src:&str){
        if dest.len() == src.len(){
            dest.copy_from_slice(src.as_bytes());
        } else if dest.len() > src.len(){
            dest[..src.len()].copy_from_slice(src.as_bytes());
        } else {
            dest.copy_from_slice(&src.as_bytes()[..dest.len()]);
        }
    }
    

    如果它最终在多字节字符的边界上切片,该函数也不会恐慌。

    编辑:Added Plaground link

    【讨论】:

      猜你喜欢
      • 2021-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多