Rust如何编写正确Trait约束,实现Array1<T>泛型的unit方法
正确的泛化实现代码如下:
use ndarray::{Array1, NdFloat}; use std::ops::Div; trait Unit<T> { fn unit(&self) -> Array1<T>; } impl<T: NdFloat> Unit<T> for Array1<T> where Array1<T>: Div<T, Output = Array1<T>>, { fn unit(&self) -> Array1<T> { let norm = (self * self).sum().sqrt(); self / norm } }
如果需要手动展开约束不使用NdFloat的话,也可以用以下写法:
use ndarray::{Array1, ScalarOperand}; use num_traits::Float; use std::ops::{Mul, Div}; trait Unit<T> { fn unit(&self) -> Array1<T>; } impl<T> Unit<T> for Array1<T> where T: Float + ScalarOperand, for<'a> &'a Array1<T>: Mul<Output = Array1<T>>, Array1<T>: Div<T, Output = Array1<T>>, { fn unit(&self) -> Array1<T> { self / (self * self).sum().sqrt() } }
约束说明
NdFloat是ndarray提供的专用于浮点数的组合trait,已经自动包含了浮点数算术运算、标量运算支持、求和等所需的所有T层面约束,不需要单独为T逐个加算术运算约束。- 生命周期约束
for<'a> &'a Array1<T>: Mul<Output = Array1<T>>保证任意生命周期的数组引用做乘法后,返回拥有所有权的数组对象,匹配self * self的运算逻辑。 Array1<T>: Div<T, Output = Array1<T>>保证数组除以标量T后返回数组,匹配self / norm的运算逻辑。
内容的提问来源于stack exchange,提问作者zareami10
相关产品推荐
相关产品推荐

