2015-03-17 1 views
3

Этот код (also on play)Производить клонирование для массива чего-то, что является клоном?

use std::sync::Arc; 

struct Foo { 
    x: isize, // Something complex in actual code, implements Drop 
} 

#[derive(Clone)] 
struct Good { 
    a: Option<Arc<Foo>>, 
    b: Option<Arc<Foo>>, 
    c: Option<Arc<Foo>>, 
} 

#[derive(Clone)] 
struct Bad { 
    x: [Option<Arc<Foo>>; 3], 
} 

fn main() { 
    println!("See?"); 
} 

терпит неудачу для Bad с

<anon>:16:5: 16:29 error: the trait `core::marker::Copy` is not implemented for the type `alloc::arc::Arc<Foo>` [E0277] 
<anon>:16  x: [Option<Arc<Foo>>; 3], 
       ^~~~~~~~~~~~~~~~~~~~~~~~ 
<anon>:14:10: 14:15 note: in expansion of #[derive_Clone] 

, но он не имеет никаких проблем с Good.

  • Почему это и
  • есть ли обходной путь? Я не очень люблю обрабатывать 12 независимых полей.

ответ

4

Проблема заключается в implementation of the Clone trait:

impl<T> Clone for [T; 4] where T: Copy 

Это делает реальный вопрос о: почему мы требуем Copy клонировать массив? That implementation говорит:

fn clone(&self) -> [T; $N] { 
    *self 
} 

Так в настоящее время, клон массива является просто копией бит-в-бит из исходного массива. Более глубокий почему может быть получен от кого-то более осведомленного.

+2

Более важный вопрос, следует ли считать его ошибкой (неполной функцией)? –

+0

Вне рук я бы не знал, как автоматизировать реализацию. Код должен быть '[self [0] .clone(), self [1] .clone(), ..., self [N-1] .clone()]', который довольно сложно сгенерировать с помощью макросы. – delnan

+1

@ delnan: Я думаю, что можно сделать что-то из этого: http://is.gd/CQAIDd – Levans