有没有办法在 Rust 的循环中使用简洁的静态调度?

Is there a way to use concise static dispatch inside a loop in Rust?

提问人:Nic 提问时间:10/17/2023 更新时间:10/17/2023 访问量:73

问:

我有一个for循环,其中第一次迭代是一个特例。唯一的区别是一个变量的类型,即使它们都实现了相同的特征。我想知道我是否以及如何使它更简洁。

有一种具体类型称为 。它实现了 trait with 方法,用于各种 Ts.值得注意的是,实现了 FooTrait<&Concrete>。ConcreteFooTrait<T>foo<T>(&mut self, modifier: T)

我有一个函数,看起来像这样:bar()

pub fn bar(slice_len, initial: &Concrete) {
    let concrete_slice[Concrete; slice_len] = initialize_slice();
    let mut carry: &Concrete = initial;
    for i in 0..concrete_slice.len() {
        concrete_slice[i].foo(carry);
        carry = &concrete_slice;
    }
    epilogue(carry);
}

我想允许它通过使用泛型来获取不同类型的初始值。(注意:该函数必须能够接受匿名类型,因为某些类型在单独的 crate 中是私有的。

pub fn bar<T>(slice_len, initial: T)
where
    Concrete: FooTrait<T>
{
    let concrete_slice[Concrete; slice_len] = initialize_slice();
    if slice_len > 0 {
        concrete_slice[0].foo(initial);
        let mut carry: &Concrete = &concrete_slice[0];
        for i in 1..concrete_slice.len() {
            concrete_slice[i].foo(carry);
            carry = &concrete_slice[i];
        }
        epilogue(carry);
    } else {
        epilogue(initial);
    }
}

显然,这是一个通用和简化的示例,我的实际代码更复杂。为了可读性,我宁愿它看起来更接近第一个而不是第二个。

我知道如果我想围绕多种不同的类型制作包装器,我可以使用枚举。但是,如果有一种方法可以在不使代码不那么简洁的情况下使用枚举,我不知道。我也知道特征对象是一回事,但这些对象有运行时成本。有没有更好的成语?

泛型 Rust 习语 代码重复

评论

4赞 kmdreko 10/17/2023
我不相信你能像你的第一个代码示例那样简洁地做到这一点。你也许可以把它隐藏在一个聪明的宏中,但我觉得这比澄清更模糊。
0赞 cdhowie 10/17/2023
即使你可以把它隐藏在枚举后面,在每次迭代中分支的运行时性能成本也可能不值得。
0赞 Nic 10/17/2023
@cdhowie -O3 会解决这个问题吗?
0赞 cafce25 10/17/2023
如何?优化无法删除必要的分支!?
0赞 cdhowie 10/17/2023
@Nic我的意思是,如果编译器展开循环的第一次迭代,然后证明所有后续迭代始终采用一个特定的分支臂,这是可能的。您必须查看生成的程序集才能确定。

答: 暂无答案