我如何有效地实施:

fn shorten(arg: [u8; 32]) -> [u8; 30] {
    ???
}

它丢弃了最后两个字节?

显然,我可以使用for循环,并在堆栈上创建一个新的较短的array.

对于编译器来说,appears有机会将[u8; 32]留在堆栈上,并且只使用其中的[u8; 30].

通常我会使用切片,但在这里我需要返回一个较短的array.

推荐答案

这是直截了当的答案没有多大价值的问题之一.但让我们从直截了当的答案开始:您可以将函数实现为

fn shorten(arg: [u8; 32]) -> [u8; 30] {
    std::array::from_fn(|i| arg[i])
}
// or
fn shorten(arg: [u8; 32]) -> [u8; 30] {
    arg[..30].try_into().unwrap()
}
// or
fn shorten(arg: [u8; 32]) -> [u8; 30] {
    let mut ret = [0; 30];
    ret.copy_from_slice(&arg[..30]);
    ret
}
// or
fn shorten(arg: [u8; 32]) -> [u8; 30] {
    let mut ret = [0; 30];
    for i in 0..30 {
        ret[i] = arg[i];
    }
    ret
}

忽略函数调用的脚手架,这些指令都优化为四条x86指令.

movups  xmm0, xmmword ptr [rsi]
movups  xmm1, xmmword ptr [rsi + 14]
movups  xmmword ptr [rdi + 14], xmm1
movups  xmmword ptr [rdi], xmm0

(看到有重叠加载/存储的诡计了吗?聪明的.-.-)godbolt

现在,对于不直接的答案:问题是,孤立地看待fn shorten个是没有意义的:

  • 只要shorten是它自己的函数并返回拥有的[u8; 30],它就必须复制,因为返回值是与参数不同的值.它不能返回指向参数的指针,因为签名promise 返回值.
  • shorten是短的,LLVM肯定会内联它.然后问题是,LLVM是否能计算出,无论使用shorten的结果是什么,都会对[u8; 32]满意.它是否能做到这一点并不能用你提供的信息来回答.

最后,shorten是四条x86指令.您是否真的处于这样一种情况:这会占用您的执行时间的很大一部分?

Rust相关问答推荐

为什么函数不接受选项T参数的所有权?

什么是Rust惯用的方式来使特征向量具有单个向量项的别名?

在泛型 struct 的字段声明中访问关联的Conant

当第二个`let`依赖于第一个`let()`时,如何在一行中有多个`let()`?

在UdpSocket上使用sendto时的隐式套接字绑定

Rust类似功能是C++命名空间吗?

我是否可以在Ruust中修改 struct 实例上的字符串,以使其在修改后具有相同的字符串生存期?

作为1字节位掩码的布尔值 struct

如果变量本身不是None,如何返回;如果没有,则返回None&Quot;?

在Rust中克隆源自INTO_ITER()的迭代器的成本?

这是什么:`impl Trait for T {}`?

确保参数是编译时定义的字符串文字

为什么编译器看不到这个 `From` impl?

std mpsc 发送者通道在闭包中使用时关闭

std::vector::shrink_to_fit 如何在 Rust 中工作?

如何刷新 TcpStream

从 HashMap>, _> 中删除的生命周期问题

如果不满足条件,如何在 Rust 中引发错误

如何将 while 循环内的用户输入添加到 Rust 中的向量?

如何在 Rust 中使用特征标志来捕获多行代码?