gpt4 book ai didi

rust - 当类型参数相同时使用不同的 impl

转载 作者:行者123 更新时间:2023-11-29 07:58:45 27 4
gpt4 key购买 nike

我有一个带有两个通用 typenum 参数的实现。当参数相同时,impl 的函数应该返回不同的类型。 (不同类型是一种更紧凑的表示,只有当类型参数相同时才能实现。)是否可以使用基于类型相等性的不同实现?下面的朴素方法会产生“冲突实现”错误,因为 Rust 没有采用更具体的实现。

extern crate typenum;
use typenum::Unsigned;

use std::ops::Mul;
use std::marker::PhantomData;

struct Matrix<N: Unsigned, M: Unsigned> {
n: usize,
m: usize,
elements: Vec<f64>,
_marker: PhantomData<(N, M)>
}

// The more compact representation
struct SquareMatrix<N: Unsigned> {
n: usize,
elements: Vec<f64>,
_marker: PhantomData<(N)>
}

impl<N: Unsigned, D: Unsigned, M: Unsigned> Mul<Matrix<D, M>> for Matrix<N, D> {
type Output = Matrix<N, M>;
fn mul(self, rhs: Matrix<D, M>) -> Self::Output {
unimplemented!()
}
}

// The more specific implementation
impl<N: Unsigned, D: Unsigned> Mul<Matrix<D, N>> for Matrix<N, D> {
type Output = SquareMatrix<N>;
fn mul(self, rhs: Matrix<D, N>) -> Self::Output {
unimplemented!()
}
}

最佳答案

您现在可以在稳定的 Rust 中执行此操作,它只需要一些额外的样板。

首先,我们将创建一个内部乘法特征来完成实际工作:

pub trait MulPrivate<Rhs, AreEqual> {
type Output;
fn mul_private(self, rhs: Rhs) -> Self::Output;
}

注意额外的类型参数:这是我们区分这两种情况的方式。

然后,我们将常规的 Mul 实现调用到这个内部实现:

use typenum::{IsEqual, Eq};
impl<N, M, D> Mul<Matrix<D, M>> for Matrix<N, D>
where D: Unsigned,
M: Unsigned,
N: Unsigned + IsEqual<M>,
Matrix<N, D>: MulPrivate<Matrix<D, M>, Eq<N, M>>,
{
type Output = <Matrix<N, D> as MulPrivate<Matrix<D, M>, Eq<N, M>>>::Output;
fn mul(self, rhs: Matrix<D, M>) -> Self::Output {
self.mul_private(rhs)
}
}

这使我们能够比较 NM。如果它们相等,则该额外类型参数将为 True,否则将为 False。现在我们可以自由地制作 MulPrivate 的两种不同实现:

use typenum::{True, False};
impl<N: Unsigned, D: Unsigned, M: Unsigned> MulPrivate<Matrix<D, M>, False> for Matrix<N, D> {
type Output = Matrix<N, M>;
fn mul_private(self, rhs: Matrix<D, M>) -> Self::Output {
println!("not square!");
unimplemented!()
}
}

// The more specific implementation
impl<N: Unsigned, D: Unsigned> MulPrivate<Matrix<D, N>, True> for Matrix<N, D> {
type Output = SquareMatrix<N>;
fn mul_private(self, rhs: Matrix<D, N>) -> Self::Output {
println!("square!");
unimplemented!()
}
}

注意一次 this issue已解决,您将能够摆脱所有这些样板文件并将其写为:

impl<N: Unsigned, D: Unsigned, M: Unsigned> Mul<Matrix<D, M>> for Matrix<N, D> where N: IsEqual<M, Output = False> {
type Output = Matrix<N, M>;
fn mul(self, rhs: Matrix<D, M>) -> Self::Output {
unimplemented!()
}
}

// The more specific implementation
impl<N: Unsigned, D: Unsigned> Mul<Matrix<D, N>> for Matrix<N, D> where N: IsEqual<N, Output = True> {
type Output = SquareMatrix<N>;
fn mul(self, rhs: Matrix<D, N>) -> Self::Output {
unimplemented!()
}
}

关于rust - 当类型参数相同时使用不同的 impl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43021272/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com