rust - 更新到 Rust 1.18 破坏了编译 : E0034 multiple applicable items in scope for "clone_into"

标签 rust

我有这个简单的代码片段,它使用一个竞技场进行内存分配和一个特征CloneInto,其目的是将一个未知来源的结构克隆到一个竞技场中,调整生命周期:

struct Arena;

impl Arena {
    fn insert<'a, T: 'a>(&'a self, _: T) -> &'a mut T { unimplemented!() }
}

trait CloneInto<'a> {
    type Output: 'a;
    fn clone_into(&self, arena: &'a Arena) -> Self::Output;
}

它可以按原样使用:

#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
struct Simple<'a> { a: &'a usize }

impl<'a, 'target> CloneInto<'target> for Simple<'a> {
    type Output = Simple<'target>;

    fn clone_into(&self, arena: &'target Arena) -> Simple<'target> {
        Simple { a: arena.insert(*self.a) }
    }
}

fn main() {
    let arena = Arena;
    let _ = Simple { a: &1 }.clone_into(&arena);
}

或者可以,直到更新到 Rust 1.18。现在 compiler emits this error :

error[E0034]: multiple applicable items in scope
  --> <anon>:25:30
   |
25 |     let _ = Simple { a: &1 }.clone_into(&arena);
   |                              ^^^^^^^^^^ multiple `clone_into` found
   |
note: candidate #1 is defined in an impl of the trait `CloneInto` for the type `Simple<'_>`
  --> <anon>:18:5
   |
18 | /     fn clone_into(&self, arena: &'target Arena) -> Simple<'target> {
19 | |         Simple { a: arena.insert(*self.a) }
20 | |     }
   | |_____^
   = note: candidate #2 is defined in an impl of the trait `std::borrow::ToOwned` for the type `_`

即使我什至没有导入 stdToOwned!

最佳答案

这是 Rust 中方法解析工作方式的不幸影响。与其他具有重载功能的语言不同,在 Rust 中,必须明确地解析要调用的确切函数,而不考虑其参数。

在这种特定情况下,Rust 1.18 带来了一个名为 clone_into 的新夜间方法。在 ToOwned 特征上,并且 ToOwned 特征是无条件地为所有实现 Clone 的类型实现并自动导入(通过 prelude )。

这个方法不能在 stable 上调用的事实没有关系;方法首先考虑解析,实际使用会报错。

请注意,尽管令人厌烦,但这种解决方法还是有好处的:人们通常不清楚选择了哪个重载,而当几个重载似乎可用时,或者为什么没有选择预期的重载。通过在明确性方面犯错,Rust 使其成为一个无需动脑筋的人。

不幸的是,在这种情况下,这会导致 Simple::clone_into() 变得不明确。

没有办法选择退出 ToOwned 实现(不是不放弃 CloneCopy),所以必须切换使用 Fully Qualified Syntax (FQS) 明确调用 clone_into :

fn main() {
    let arena = Arena;
    let _ = CloneInto::clone_into(&Simple { a: &1 }, &arena);
}

关于rust - 更新到 Rust 1.18 破坏了编译 : E0034 multiple applicable items in scope for "clone_into",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44483876/

相关文章:

types - 如何修复 "implicitly returns '()' as its body has no tail or ' return'表达式?

rust - 为什么要为 &File 和 &TcpStream 实现 Write trait?安全吗?

rust - 如何结合逐行读取文件和遍历每一行中的每个字符?

memory-management - 为什么在不存储结果的情况下两次调用Box::new却分配了相同的堆地址?

string - 如何复制 String 或 str

rust - 有没有办法告诉编译器没有人会为引用泛型类型实现特征?

rust - 如何将格式化字符串写入文件?

rust - 我如何使用-Zprofile为nostd内核生成代码覆盖率

rust - 如何获取多维数组的维度?

rust - 如何将尾递归重写为循环?