Reputation: 2127
The example below is just an example, I know I don't need the Clone for this to work, but if S
were an enum with [T]
and Vec<T>
and I wanted to resize the vector, T
would have to be Clone
.
struct S<'a, T>{
a: &'a [T]
}
impl<'a, T> S<'a, T> {
pub fn borrow(&self) -> &[T]
where [T]: Clone {
self.a
}
}
fn main() {
let slice:[u8;3] = [1,2,3];
let x = S{a: &slice};
x.borrow();
}
Error:
error[E0277]: the trait bound `[u8]: Clone` is not satisfied
--> src/main.rs:17:7
|
17 | x.borrow();
| ^^^^^^ the trait `Clone` is not implemented for `[u8]`
So, why isn't [u8]
Clone
?
Upvotes: 2
Views: 1106
Reputation: 58715
So why isn't
[u8]
Clone
?
Look at the type of the clone
method in the definition of Clone
:
pub trait Clone {
pub fn clone(&self) -> Self;
// more stuff omitted..
}
It returns Self
, which would be [u8]
in this case. The problem is that [u8]
is not Sized
, that is, since we don't know how many elements it will have we can't know its size at compile time. But returning it from this method would mean that it is moved onto the stack, which is not possible if the compiler doesn't know how much space to leave for it.
Upvotes: 5
Reputation: 1109
I was able to get your code to compile by adding the &
to the where clause:
impl<'a, T> S<'a, T> {
pub fn borrow(&self) -> &[T]
where
&'a [T]: Clone,
{
self.a
}
}
The key here being that the slice is the reference to a contiguous set of values: &[u32]
.
As to why, [u32]
does not implement Clone
: I believe the reason is that it doesn't have any information as to how many elements are in the range of memory. Whereas the slice type,&[u32]
, contains a reference to the start of a series of u32
values in memory and how many elements there are. Without the number of elements, cloning the data would be impossible.
Upvotes: 2