rust - 将特征方法和关联类型标记为默认的专业化时,预期的输出类型会发生变化
问题描述
我想为Rust中的大多数类型实现模运算:Rem
#![feature(specialization)]
use std::ops::{Add, Rem};
/// Define a modulo operation, in the mathematical sense.
/// This differs from Rem because the result is always non-negative.
pub trait Modulo<T> {
type Output;
#[inline]
fn modulo(self, other: T) -> Self::Output;
}
/// Implement modulo operation for types that implement Rem, Add and Clone.
// Add and Clone are needed to shift the value by U if it is below zero.
impl<U, T> Modulo<T> for U
where
T: Clone,
U: Rem<T>,
<U as Rem<T>>::Output: Add<T>,
<<U as Rem<T>>::Output as Add<T>>::Output: Rem<T>
{
default type Output = <<<U as Rem<T>>::Output as Add<T>>::Output as Rem<T>>::Output;
#[inline]
default fn modulo(self, other: T) -> Self::Output {
((self % other.clone()) + other.clone()) % other
}
}
这在没有 s 的情况下编译得很好default
,但是有了default
,我得到了
error[E0308]: mismatched types
--> main.rs:
|
| default fn modulo(self, other: T) -> Self::Output {
| ------------ expected `<U as Modulo<T>>::Output` because of return type
| ((self % other.clone()) + other.clone()) % other
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected Modulo::Output, found std::ops::Rem::Output
|
= note: expected type `<U as Modulo<T>>::Output`
found type `<<<U as std::ops::Rem<T>>::Output as std::ops::Add<T>>::Output as std::ops::Rem<T>>::Output`
我不明白为什么会这样。我需要default
s 因为我想将它专门用于Copy
类型。
我每晚使用 Rust 1.29.0。
解决方案
这是问题的较小再现(一个MCVE):
#![feature(specialization)]
trait Example {
type Output;
fn foo(&self) -> Self::Output;
}
impl<T> Example for T {
default type Output = i32;
default fn foo(&self) -> Self::Output {
42
}
}
fn main() {}
出现问题是因为此实现的专门化可以选择专门化,也可以选择专门化,Output
但foo
不必两者都做:
impl<T> Example for T
where
T: Copy,
{
type Output = bool;
}
在这种情况下,最初的实现foo
将不再有意义——它不再返回类型值Self::Output
。
当前的专业化实现要求您同时考虑本地和全局,这是您必须在其中阅读错误消息的上下文。这并不理想,但是像这样的问题(以及许多更复杂的事情,我敢肯定)是其中的一部分还不稳定的原因。
推荐阅读
- c++ - CPP 中的 ++ 运算符是否对 char 有任何重载?
- python - 为列表列表中的每个列表映射一个函数
- python - 如何让 Pandas 从下一行开始在新列中创建 sumsum?
- mfc - MFC CImageList DeleteImageList() vs Remove()
- android - Android studio 线性布局问题:我应该如何在没有嵌套权重的情况下布局我的?
- python - 16位PNG的像素值20930不应该是灰色阴影吗?
- numpy - Python 向量没有列大小?/ Theta 初始化为全 0
- python - 如何在不手动下载模型的情况下访问/使用谷歌预训练的 Word2Vec 模型?
- c - 我的 Visual Studio 2015 找不到构建项目的基本依赖项
- git - git checkout -b dev remote_repo/dev 没有从远程获取所有提交