对数组进行操作,例如平方长度。
拥有通用类型(例如f32
,f64
)非常有用,但您可能还需要通用长度,但不动态长度。
这是一个带有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。
是否可以定义通用函数,其中大小不是动态的,而是泛型的,类型可以是通用的相同方式吗?
答案 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来做到这一点,但它有点混乱,但应该在这里做你想做的事。我自己也避免了。
rfcs和compiler都有语言级别的进展,以及围绕完整的const依赖类型的持续讨论。因此,我希望在不久的将来不要弃用通用阵列箱。