I have a trait Input
that adds a to_custom_bytes()
method to String
s and u64
s.
trait Input {
fn to_custom_bytes(&self) -> Vec<u8>;
}
impl Input for u64 {
fn to_custom_bytes(&self) -> Vec<u8> {
self.to_le_bytes().to_vec()
}
}
impl Input for String {
fn to_custom_bytes(&self) -> Vec<u8> {
self.as_bytes().to_vec()
}
}
I have a function that takes a Vector of items that implement that trait:
fn inputs_to_custom_bytes(inputs: Vec<impl Input>) -> Vec<u8> {
let mut bytes: Vec<u8> = Vec::new();
for input in inputs {
bytes.extend(input.to_custom_bytes());
}
bytes
}
Why does Rust compiler complain expected 'String', found 'u64'
for age, when age implements this Trait and the argument is Vec<impl Input>
not Vec<String>
?
pub fn main() {
let name = String::from("steve");
let age: u64 = 20;
let custom_bytes: Vec<u8> = inputs_to_custom_bytes(vec![name, age]);
}
impl
in a generic parameter means one such type, so can't be used for multiple types at the same time. Thus a function accepting Vec<impl Input>
can be called with a Vec<u64>
or a Vec<String>
, but there is no concrete type called Vec<impl Input>
; that's a generic type parameter.
dyn
can be used instead of impl
, for trait objects, which allow mixing multiple types of values, using runtime lookup to call the correct function at runtime. So you should be able to accomplish something similar with a Vec<&dyn Input>
.
pub fn inputs_to_custom_bytes(inputs: Vec<&dyn Input>) -> Vec<u8> {
let mut bytes: Vec<u8> = Vec::new();
for input in inputs {
bytes.extend(input.to_seeds());
}
bytes
}