【问题标题】:error: reached the recursion limit while auto-dereferencing T错误:在自动取消引用 T 时达到递归限制
【发布时间】:2014-12-02 22:54:53
【问题描述】:

不知道这是正常现象还是bug:

struct A<T> (T);

impl<T> Add<A<T>, A<T>> for A<T> 
where T: Add<T, T> + Deref<T> + Copy {
    fn add(&self, &A(b): &A<T>) -> A<T> {
        let A(a) = *self;
        A(a.add(&b))
    }
}

产生这个错误:

<anon>:7:11: 7:12 error: reached the recursion limit while auto-dereferencing T [E0055]
<anon>:7         A(a.add(&b))

a.add(&amp;b) 替换为a+b 时编译不会出错

playpen

a+b不应该只是a.add(&amp;b)的糖吗?

【问题讨论】:

    标签: rust


    【解决方案1】:

    简短版: T 实现 Deref&lt;T&gt; 毫无意义,因此在解除对左侧的引用方面,方法调用和运算符调用的工作方式有所不同,因为 @987654324 @a.add(&amp;b)完全一样。

    加长版:

    就获取引用而言,+ 运算符和 Add.add 的操作方式不同。

    + 运算符 通过引用本身获取两个操作数。 a + b 对于 AB 各自类型的操作数要求有 Add&lt;B, C&gt; 的实现 A 并将产生一个类型为 C 的值。如前所述,ab 被引用;它会默默地自己制作这些引用;没有猜测。它们的工作原理如下:

    let a = 1i;
    let b = a + a;    // this one works
    let c = a + &a;   // mismatched types: expected `int`, found `&int` (expected int, found &-ptr)
    let d = &a + a;   // binary operation `+` cannot be applied to type `&int`
    let e = &a + &a;  // binary operation `+` cannot be applied to type `&int`
    

    在任何情况下都不会取消引用,因此狡猾的T: Deref&lt;T&gt; 要求不会破坏任何东西。

    Add.add 通过引用获取这两个值。作为常规函数调用,它具有在必要时自动取消引用和引用左侧的能力。虽然右侧作为方法参数按原样传入,但左侧被尽可能地取消引用以找到所有可能由add 表示的方法。通常这很好,它会做你想做的事,但在这种情况下它不会,因为Ta 是哪个类型)实现了Deref&lt;T&gt;。所以取消引用得到了T。然后T,实现Deref&lt;T&gt;,取消引用T。更重要的是,T 实现了Deref&lt;T&gt;,因此取消了对T 的引用。它一直这样做,直到达到递归限制。真的,T 实现 Deref&lt;T&gt; 完全没有意义。

    为了比较,下面是方法调用 add 工作原理的一些演示:

    let a = 1i;
    let b = a.add(a);      // mismatched types: expected `&int`, found `int` (expected &-ptr, found int)
    let c = a.add(&a);     // this one works (a reference to the LHS is taken automatically)
    let d = (&a).add(a);   // mismatched types: expected `&int`, found `int` (expected &-ptr, found int)
    let e = (&a).add(&a);  // this one works (LHS is dereferenced and then rereferenced)
    

    【讨论】:

    • 感谢您的清晰解释!我添加了 deref 特征,认为它只是意味着可以取消引用 T(以纠正我的代码中的其他错误),这并不是它的真正含义。但值得对a+ba.add(&amp;b) 之间的区别进行解释
    猜你喜欢
    • 2019-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    • 2021-11-25
    • 1970-01-01
    • 2019-06-22
    • 1970-01-01
    相关资源
    最近更新 更多