作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个带有两个通用 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)
}
}
这使我们能够比较 N
和 M
。如果它们相等,则该额外类型参数将为 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/
现在我正在尝试实现 flash programming specification对于 PIC32MX。我正在使用 PIC32MX512L 和 PIC32MX512H。 PIC32MX512L最终必须
我是一名优秀的程序员,十分优秀!