在许多情况下,我需要清除缓冲区区域或将切片设置为特定值。推荐的原生方法是什么?
这是无效的Rust,但是我想做类似的事情:
let mut some_buffer = vec![0u8; 100];
buffer[10..20].set(0xFF)
我可以使用for循环,但由于我是Rust的新手,所以我感觉自己缺少一些东西。
在C ++中,我会做类似的事情:
std::array<int,6> foobar;
foobar.fill(5);
在Python中,它会类似:
tmp = np.zeros(10)
tmp[3:6]=2
答案 0 :(得分:11)
您不是唯一的一个。对于同一件事存在功能请求/ RFC:
但是,您将购物车放在马匹前面。您真的关心它叫memset
吗?我猜不会,只是它是有效的。 Rust的一个主要优点是,编译器可以在构建时“丢弃”许多抽象。例如,为什么当某些CPU指令执行相同的操作时调用函数?
pub fn thing(buffer: &mut [u8]) {
for i in &mut buffer[10..20] { *i = 42 }
}
playground::thing:
pushq %rax
cmpq $19, %rsi
jbe .LBB0_1
movabsq $3038287259199220266, %rax
movq %rax, 10(%rdi)
movw $10794, 18(%rdi)
popq %rax
retq
.LBB0_1:
movl $20, %edi
callq core::slice::slice_index_len_fail@PLT
ud2
pub fn thing(buffer: &mut [u8]) {
for i in &mut buffer[10..200] { *i = 99 }
}
.LCPI0_0:
.zero 16,99
playground::thing:
pushq %rax
cmpq $199, %rsi
jbe .LBB0_1
movaps .LCPI0_0(%rip), %xmm0
movups %xmm0, 184(%rdi)
movups %xmm0, 170(%rdi)
movups %xmm0, 154(%rdi)
movups %xmm0, 138(%rdi)
movups %xmm0, 122(%rdi)
movups %xmm0, 106(%rdi)
movups %xmm0, 90(%rdi)
movups %xmm0, 74(%rdi)
movups %xmm0, 58(%rdi)
movups %xmm0, 42(%rdi)
movups %xmm0, 26(%rdi)
movups %xmm0, 10(%rdi)
popq %rax
retq
.LBB0_1:
movl $200, %edi
callq core::slice::slice_index_len_fail@PLT
ud2
与kazemakase points out一样,当设置区域变得“足够大”时,优化器将切换为使用memset
而不是内联指令:
pub fn thing(buffer: &mut [u8]) {
for i in &mut buffer[11..499] { *i = 240 }
}
playground::thing:
pushq %rax
cmpq $498, %rsi
jbe .LBB0_1
addq $11, %rdi
movl $240, %esi
movl $488, %edx
callq memset@PLT
popq %rax
retq
.LBB0_1:
movl $499, %edi
callq core::slice::slice_index_len_fail@PLT
ud2
如果愿意,可以将此功能包装在扩展特性中
trait FillExt<T> {
fn fill(&mut self, v: T);
}
impl FillExt<u8> for [u8] {
fn fill(&mut self, v: u8) {
for i in self {
*i = v
}
}
}
pub fn thing(buffer: &mut [u8], val: u8) {
buffer[10..20].fill(val)
}
另请参阅:
答案 1 :(得分:1)
从 2021 年 2 月 11 日发布的 Rust 1.50.0 开始,slice::fill
现在是稳定的,这意味着如果您更改函数名称,您的示例现在可以运行:
let mut buffer = vec![0u8; 20];
buffer[5..10].fill(0xFF);
println!("{:?}", buffer);
将打印[0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]