似乎在派生時Clone
,Rust 將Clone
trait 要求轉發給不需要 trait 的泛型,就像它們被包裹在Arc
.
我誤解了它Clone
的作業原理還是編譯器錯誤?
考慮以下代碼,其中a.clone()
有效,但b.clone()
無效。另請注意,沒有b.clone()
呼叫,代碼編譯良好,表明#[derive(Clone)]
有效。
use std::sync::Arc;
struct Unclonable {}
struct A<T>(Arc<T>);
impl<T> Clone for A<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
#[derive(Clone)]
struct B<T>(Arc<T>);
fn main() {
let a = A(Arc::new(Unclonable {}));
let b = B(Arc::new(Unclonable {}));
// Works
a.clone();
// Fails
b.clone();
}
|
3 | struct Unclonable {}
| ----------------- doesn't satisfy `Unclonable: Clone`
...
13 | struct B<T>(Arc<T>);
| --------------------
| |
| method `clone` not found for this
| doesn't satisfy `B<Unclonable>: Clone`
...
22 | b.clone();
| ^^^^^ method cannot be called on `B<Unclonable>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`Unclonable: Clone`
which is required by `B<Unclonable>: Clone`
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `clone`, perhaps you need to implement it:
candidate #1: `Clone`
help: consider annotating `Unclonable` with `#[derive(Clone)]`
|
3 | #[derive(Clone)]
|
當我展開宏時,我看到以下生成的代碼:
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2018::*;
#[macro_use]
extern crate std;
use std::sync::Arc;
struct Unclonable {}
struct A<T>(Arc<T>);
impl<T> Clone for A<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
struct B<T>(Arc<T>);
#[automatically_derived]
#[allow(unused_qualifications)]
impl<T: ::core::clone::Clone> ::core::clone::Clone for B<T> {
#[inline]
fn clone(&self) -> B<T> {
match *self {
B(ref __self_0_0) => B(::core::clone::Clone::clone(&(*__self_0_0))),
}
}
}
fn main() {
let a = A(Arc::new(Unclonable {}));
let b = B(Arc::new(Unclonable {}));
a.clone();
b.clone();
}
到底是怎么回事?為什么 rust 編譯器會添加<T: ::core::clone::Clone>
??
或者這只是其中一種預期方式是Clone
手動實作的情況?
uj5u.com熱心網友回復:
這不是一個編譯器錯誤,從某種意義上說,它是一種記錄在案的行為,盡管人們可能會覺得它很奇怪。編譯器會在派生時自動向泛型型別添加約束,即使實作中實際上不需要這些約束。例如,派生Clone
forB<T>
只會實作Clone for B<T>
where T: Clone
,即使它可能會實作 that 而不管T
is Clone
。
所以,就目前而言(也許編譯器將來會對這些情況變得更聰明),是的,這是你必須手動實作的情況之一。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/470393.html
上一篇:Node.jsPromise.all方法無法按預期作業以保存多個貓鼬檔案
下一篇:Go泛型:無效的復合文字型別T