rust 编译时是否可以拆分&str?

vbopmzt1  于 2023-03-23  发布在  其他
关注(0)|答案(1)|浏览(121)

我正在创建一个宏,它对一个由空格分隔的数字列表执行include_bytes!操作:
如何在编译时创建这些数字的u64切片?我尝试转换为字符串,然后调用split(" "),但split迭代了它,而不是const

kuhbmx9i

kuhbmx9i1#

users.rust-lang论坛的回答提供了一个可行的解决方案:(playground)

const fn to_u64(bytes: &[u8], start: usize, end: usize) -> u64 {
    let mut res: u64 = 0;
    let mut i = start;

    while i < end {
        res = 10 * res + (bytes[i] - b'0') as u64;

        i += 1;
    }

    res
}

const fn split_parse<const LEN: usize>(bytes: &[u8]) -> [u64; LEN] {
    let mut res = [0; LEN];

    let mut idx_start = 0;
    let mut idx_curr = 0;
    let mut i = 0;

    while i < LEN {
        while idx_curr < bytes.len() && bytes[idx_curr] != b' ' {
            idx_curr += 1;
        }
        res[i] = to_u64(bytes, idx_start, idx_curr);
        idx_curr += 1;
        idx_start = idx_curr;
        i += 1;
    }

    res
}

const fn split_len(bytes: &[u8]) -> usize {
    let mut len = 1;
    let mut i = 0;
    while i < bytes.len() {
        if bytes[i] == b' ' {
            len += 1;
        }
        i += 1;
    }
    len
}

const DATA: &[u8] = b"1 2 3 4 5";
// In the actual use case, you'd use include_bytes here
// const DATA: &[u8] = include_bytes!("numbers.txt");
const DATA_LEN: usize = split_len(DATA);
static DATA_INTS: [u64; DATA_LEN] = split_parse(DATA);

fn main() {
    println!("{:?}", DATA_INTS);
}

这个解决方案使用const函数而不是宏。它假设输入是有效的,但是如果你想验证输入,你可以使用panic。例如,在to_u64中,你可以检查字符是否是数字:

if b'0' > bytes[i] || b'9' < bytes[i] {
    panic!("Not an integer");
}

相关问题