问题描述
在 Rust 中试验装饰器设计模式时,我遇到了我认为可能是编译器错误的问题,但我对这门语言太陌生,无法自信。
可以转换为 i64
的简单类型:
enum MyNumbers {
Zero,One,Two,}
impl From<MyNumbers> for i64 {
fn from(n: MyNumbers) -> Self {
match n {
MyNumbers::Zero => 0,MyNumbers::One => 1,MyNumbers::Two => 2,}
}
}
这里是一个可以在装饰器中使用的结构体:
struct MyWrapper<N> {
n: N,}
如果 MyWrapper<N>
可以转换为 i64
,N
可以转换为 i64
。
impl<N> From<MyWrapper<N>> for i64
where
N: Into<i64>,{
fn from(wrapper: MyWrapper<N>) -> Self {
wrapper.n.into()
}
}
这符合我的预期。
现在我希望能够从 i64
构造一个 MyWrapper
而无需消耗它。我更改了 From
trait 实现以对引用进行操作:
impl From<&MyNumbers> for i64 {
fn from(n: &MyNumbers) -> Self {
match n {
MyNumbers::Zero => 0,}
}
}
impl<'a,N> From<&'a MyWrapper<N>> for i64
where
&'a N: Into<i64>,{
fn from(wrapper: &'a MyWrapper<N>) -> Self {
(&wrapper.n).into()
}
}
但是现在...
error[E0275]: overflow evaluating the requirement `i64: From<&MyWrapper<_>>`
--> src/main.rs:34:13
|
34 | let i = i64::from(&w);
| ^^^^^^^^^
|
= help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`playground`)
= note: required because of the requirements on the impl of `Into<i64>` for `&MyWrapper<_>`
= note: required because of the requirements on the impl of `From<&MyWrapper<MyWrapper<_>>>` for `i64`
= note: 126 redundant requirements hidden
= note: required because of the requirements on the impl of `From<&MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<MyWrapper<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` for `i64`
为什么这适用于拥有的类型,而不适用于引用?
另外,这真的让我很困惑——
不调用 i64::from()
是可以的 - Playground
调用不同的 i64::from
错误 - 但不应该评估我的代码!? Playground
fn main() {
i64::from(32i32);
}
解决方法
编译错误。 https://github.com/rust-lang/rust/issues/37748
作为一种解决方法,我不得不求助于 #[derive(Copy)] 以防止我的类型在转换的每个级别被消耗。也许 From/Into 不太适合这种模式......直到语言成熟一点。