![](/img/trans.png)
[英]Why does the rust compiler require a type annotation for Option<&impl Trait>?
[英]Rust Type annotation Error in Index trait bounding
我正在嘗試使用下面的代碼實現矩陣數據結構,
use std::ops::{Add, Index, IndexMut};
use num::{One, Zero};
type Idx2<'a> = &'a [usize];
pub trait MatrixTrait {
fn zeros(shape: Idx2) -> Self;
fn ones(shape: Idx2) -> Self;
}
#[derive(Default, Debug, Clone)]
pub struct Dense2DArray<T> {
data: Vec<T>,
shape: Vec<usize>,
}
impl <T> MatrixTrait for Dense2DArray<T>
where
T: Zero + One + Clone,
{
fn zeros(shape: Idx2) -> Self {
let data = vec![T::zero(); shape[0] * shape[1]];
Self { data, shape: shape.to_vec() }
}
fn ones(shape: Idx2) -> Self {
let data = vec![T::one(); shape[0] * shape[1]];
Self { data, shape: shape.to_vec() }
}
}
impl <T> Index<Idx2<'_>> for Dense2DArray<T> {
type Output = T;
fn index(&self, index: Idx2) -> &T {
&self.data[index[0] * self.shape[1] + index[1]]
}
}
impl <T> IndexMut<Idx2<'_>> for Dense2DArray<T> {
fn index_mut(&mut self, index: Idx2) -> &mut T {
&mut self.data[index[0] * self.shape[1] + index[1]]
}
}
pub fn create_and_add_generic_matrix <'a, 'b, M, T> (a0: M) -> M
where
T: One + Add<Output=T> + Copy,
M: MatrixTrait + Index<Idx2<'a>, Output = T> + IndexMut<Idx2<'b>>,
{
let nx = 3; let ny = 2;
let mut a1 = M::zeros(&[nx, ny]);
for i in 0..nx {
for j in 0..ny {
a1[[i, j]] = a0[[i, j]] + T::one() + T::one();
}
}
a1
}
fn main() {
let nx = 3; let ny = 2;
let a0 = Dense2DArray::<f64>::ones(&[nx, ny]);
let b = create_and_add_generic_matrix(a0);
println!("{:?}", b);
}
但我總是得到錯誤:
error[E0283]: type annotations needed
--> linalg\src\matrices\mod.rs:56:26
|
56 | M: MatrixTrait + Index<Idx2<'a>, Output = T> + IndexMut<Idx2<'b>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `M`
|
= note: cannot satisfy `M: Index<&'a [usize]>`
奇怪的是,或者可能不是,如果我將類型更改為(並對代碼執行所需的更改,例如刪除生命周期):
type Idx2 = [usize; 2];
它可以正常工作,但我僅限於二維矩陣。
我不明白為什么執行索引方式的變化會影響M
的類型注釋,也不應該如何解決這個問題? 誰能幫我理解發生了什么?
謝謝。
此界限表示M
必須為某些特定的調用者指定的生命周期'a
實現Index<Idx2<'a>, Output = T>
,但您真正想要的是說它必須在任何可能的生命周期'a
中實現此特征。
你需要一個更高等級的 trait bound :
pub fn create_and_add_generic_matrix<M, T> (a0: M) -> M
where
T: One + Add<Output=T> + Copy,
M: MatrixTrait + for<'a> Index<Idx2<'a>, Output = T> + for<'a> IndexMut<Idx2<'a>>,
請注意,您還必須在for
循環中借用索引表達式,因為數組不是切片:
a1[&[i, j]] = a0[&[i, j]] + T::one() + T::one();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.