如何使用通用固定长度数组定义函数?

时间:2016-08-14 09:49:06

标签: generics rust

对数组进行操作,例如平方长度。

拥有通用类型(例如f32f64)非常有用,但您可能还需要通用长度,但动态长度。

这是一个带有2个参数的平方函数的例子。

use std::ops::{Add, AddAssign, Sub, Mul};

const CAN_THIS_BE_GENERIC: usize = 2;

fn squared_length<T>(
    a: &[T; CAN_THIS_BE_GENERIC],
    b: &[T; CAN_THIS_BE_GENERIC]
) -> T
    where T:
        Copy +
        Add +
        AddAssign +
        Add<Output=T> +
        Sub<Output=T> +
        Mul<Output=T>
{
    let mut d: T = a[0] - a[0];  // zero :(
    for (elem_a, elem_b) in a.iter().zip(b.iter()) {
        let elem_dim: T = *elem_a - *elem_b;
        d += elem_dim * elem_dim;
    }
    return d;
}

fn main() {
    println!("Length A! {}", squared_length::<f64>(&[0.5, 3.5], &[10.0, 0.0]));
    println!("Length B! {}", squared_length::<i32>(&[10, -6], &[4, 8]));
    println!("Length C! {}", squared_length::<f32>(&[-3.0, 0.0], &[9.0, 0.0]));
}

目前,矢量长度设置为2。

是否可以定义通用函数,其中大小不是动态的,而是泛型的,类型可以是通用的相同方式吗?

2 个答案:

答案 0 :(得分:8)

没有,从Rust 1.25开始就不可能。 (2018年5月)。这(通常称为“类型级整数”)是一个长期请求的功能,但它在Rust中尚不可用。

有关此主题的几个RFC。最近,一个人终于被接受了: RFC 2000 -- Const Generics 。但是,它尚未实现(tracking issue)。我预计实施最早将于2018年结束,但更可能是2019年。

有一些crates模拟类型级整数,如type-num。它有点可用,但我不会称它为完全替代品。

请注意:有时候不一定要使用类型级整数。您的示例也适用于动态大小。更好的是:因为你的函数很小,所以很可能会内联,然后优化器可能会在编译时计算出所有的大小。因此,如果性能是使用类型级整数的唯一原因,则可能没有必要。

答案 1 :(得分:1)

首先,有许多API类型级别的数字感觉很诱人,但您可以通过更直接地使用关联类型来提高灵活性。

那说..

现在有一个generic-array crate几乎可以使用前面提到的type-num来做到这一点,但它有点混乱,但应该在这里做你想做的事。我自己也避免了。

rfcscompiler都有语言级别的进展,以及围绕完整的const依赖类型的持续讨论。因此,我希望在不久的将来不要弃用通用阵列箱。