[英]using const generic in implementation of trait for another trait causes "unconstrained const parameter" error
我正在嘗試實現一些抽象的線性代數特征和結構,作為我學習 rust 實踐的一部分。 在下面的代碼中,當我為 VectorDynamic< VectorAbstract<TValue>
實現VectorDynamic<TValue>
時沒有問題; 但是當我嘗試對VectorStatic<TValue, DIM_COUNT>
執行相同操作時,我收到以下錯誤:
the const parameter `DIM_COUNT` is not constrained by the impl trait, self type, or predicates
unconstrained const parameter
note: expressions using a const parameter must map each value to a distinct output value
note: proving the result of expressions other than the parameter are unique is not supported
我在這里做錯了什么?
實現這一點的正確方法是什么?
這是我的代碼:
pub trait VectorAbstract<TValue: Scalar>: VectorSpaceElement + // a dozen std traits
{
fn dot(lhs: &Self, rhs: &Self) -> TValue;
}
pub trait VectorDynamic<TValue: Scalar>: VectorAbstract<TValue> {
fn dim_count(&self) -> usize;
fn from_list(arr: Vec<TValue>) -> Self;
}
pub trait VectorStatic<TValue: Scalar, const DIM_COUNT: usize>: VectorAbstract<TValue> {
fn from_array(arr: [TValue; DIM_COUNT]) -> Self;
}
impl<TValue: Scalar, TVector: VectorDynamic<TValue>> VectorAbstract<TValue> for TVector {
fn dot(lhs: &Self, rhs: &Self) -> TValue {
// ... dot product body for dynamic vectors ...
}
}
impl<TValue: Scalar, const DIM_COUNT: usize, TVector: VectorStatic<TValue, DIM_COUNT>>
VectorAbstract<TValue> for TVector
{
fn dot(lhs: &Self, rhs: &Self) -> TValue {
// ... dot product body for static vectors ...
}
}
更新 1
我還嘗試了以下方法:
pub trait VectorStatic<TValue: Scalar>: VectorAbstract<TValue> {
const DIM_COUNT: usize;
fn from_array(arr: [TValue; Self::DIM_COUNT]) -> Self;
}
impl<TValue: Scalar, TVector: VectorStatic<TValue>> VectorAbstract<TValue> for TVector {
fn dot(lhs: &Self, rhs: &Self) -> TValue {
// ... dot product body for static vectors ...
}
}
但是我在聲明from_array
function 時收到以下錯誤:
generic parameters may not be used in const operations
cannot perform const operation using `Self`
note: type parameters may not be used in const expressions
注意:我希望在編譯時以某種方式獲得 DIM_COUNT,因此VectorStatic
沒有fn dim_count()
。
更新 2
此外,當我完全刪除 VectorStatic 的實現時,我在另一個文件中收到另一個錯誤,其中我有一個Vector2
結構並嘗試為此實現VectorStatic<TValue, 2>
:
pub struct Vector2<TValue: Scalar> {
pub x: TValue,
pub y: TValue,
}
impl<TValue: Scalar> VectorStatic<TValue, 2> for Vector2<TValue> {
// ... implementation ...
}
這是錯誤:
the trait bound `math::algebra::vectors::vector2::Vector2<TValue>: math::algebra::abstractions::VectorDynamic<TValue>` is not satisfied
the trait `math::algebra::abstractions::VectorDynamic<TValue>` is not implemented for `math::algebra::vectors::vector2::Vector2<TValue>`
請注意,此 Vector2 結構根本不應該是VectorDynamic
。 這里肯定有一些我沒有清楚地理解的東西,也許 rust 認為我正在嘗試使每個VectorAbstract
都成為VectorDynamic
或類似的東西?
我錯過了什么?
更新 3
也許我還應該提到我已經嘗試了以下方法:
impl<TValue: Scalar> VectorAbstract<TValue> for dyn VectorDynamic<TValue>
{
fn dot(lhs: &Self, rhs: &Self) -> TValue {
// ... dot product body for dynamic vectors ...
}
}
impl<TValue: Scalar, const DIM_COUNT: usize> VectorAbstract<TValue> for dyn VectorStatic<TValue, DIM_COUNT>
{
fn dot(lhs: &Self, rhs: &Self) -> TValue {
// ... dot product body for static vectors ...
}
}
但在那種情況下,我得到了這兩個錯誤:
the trait `math::algebra::abstractions::VectorDynamic/VectorStatic` cannot be made into an object
然后有十幾行說因為他們使用Self
作為類型參數。
您的原始代碼的問題在於,不能保證類型TVector
只會實現VectorStatic<TValue, 1>
而不會實現VectorStatic<TValue, 2>
,這會導致VectorAbstract<TValue>
的實現沖突。
更新 1 是 go 的方式,因為這樣一個類型不能多次實現VectorStatic
。 目前,這需要每晚lib.rs
並在 lib.rs / main.rs
的開頭添加#![feature(generic_const_exprs)]
下一個問題將是VectorAbstract<TValue>
的 2 個impl
-s。 同樣,沒有什么可以保證TVector
不會同時實現VectorDynamic<TValue>
和VectorStatic<TValue>
,這會導致VectorAbstarct<TValue>
的實現沖突。 據我所知,即使使用不穩定的功能也無法做到這一點。 最好的方法是使用包裝結構。
VectorStatic1
+ VectorStaticWrapper1
需要添加的功能,並且僅適用於夜間 rust 版本, VectorStatic2
+ VectorStaticWrapper2
工作穩定。
#![feature(generic_const_exprs)]
pub trait Scalar {}
pub trait VectorAbstract<TValue: Scalar>:
{
fn dot(lhs: &Self, rhs: &Self) -> TValue;
}
pub trait VectorDynamic<TValue: Scalar>: VectorAbstract<TValue> {
fn dim_count(&self) -> usize;
fn from_list(arr: Vec<TValue>) -> Self;
}
pub trait VectorStatic1<TValue: Scalar>: VectorAbstract<TValue> {
const DIM_COUNT: usize;
fn from_array(arr: [TValue; Self::DIM_COUNT]) -> Self;
}
pub trait VectorStatic2<TValue: Scalar, const DIM_COUNT: usize>: VectorAbstract<TValue> {
fn from_array(arr: [TValue; DIM_COUNT]) -> Self;
}
struct VectorDynamicWrapper<T>(T);
struct VectorStaticWrapper1<T>(T);
struct VectorStaticWrapper2<T, const DIM_COUNT: usize>(T);
impl<TValue: Scalar, TVector: VectorDynamic<TValue>> VectorAbstract<TValue> for VectorDynamicWrapper<TVector> {
fn dot(lhs: &Self, rhs: &Self) -> TValue {
let lhs = &lhs.0;
let rhs = &rhs.0;
todo!()
}
}
impl<TValue: Scalar, TVector: VectorStatic1<TValue>>
VectorAbstract<TValue> for VectorStaticWrapper1<TVector>
{
fn dot(lhs: &Self, rhs: &Self) -> TValue {
let lhs = &lhs.0;
let rhs = &rhs.0;
let dim_count = TVector::DIM_COUNT;
todo!()
}
}
impl<TValue: Scalar, const DIM_COUNT: usize, TVector: VectorStatic2<TValue, DIM_COUNT>>
VectorAbstract<TValue> for VectorStaticWrapper2<TVector, DIM_COUNT>
{
fn dot(lhs: &Self, rhs: &Self) -> TValue {
let lhs = &lhs.0;
let rhs = &rhs.0;
todo!()
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.