Я определил черту Foo
, реализовал эту черту для [u32]
и написал функцию bar
, принимающую эту черту в качестве аргумента ( детская площадка ):
trait Foo {
fn foo(&self) -> u32;
}
impl Foo for [u32] {
fn foo(&self) -> u32 {
self[0]
}
}
fn bar<T>(f: &T) -> u32
where
T: Foo,
{
f.foo() + 1
}
fn main() {
let f: &[u32] = &[42];
bar(f);
}
Это не компилируется, потому что bar
неявно ожидает, что его аргументы будут Sized
:
error[E0277]: the trait bound `[u32]: std::marker::Sized` is not satisfied
--> src/main.rs:20:5
|
20 | bar(f);
| ^^^ `[u32]` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `[u32]`
note: required by `bar`
--> src/main.rs:11:1
|
11 | / fn bar<T>(f: &T) -> u32
12 | | where
13 | | T: Foo,
14 | | {
15 | | f.foo() + 1
16 | | }
| |_^
Я могу исправить это с помощью T: Foo + ?Sized
, но тогда мне придется сделать это для каждые функция, ожидающая Foo
, что вызывает боль ...
Можно ли раз и навсегда объявить, что реализации Foo
не следует ожидать Sized
?Я попытался trait Foo: ?Sized
в строке 1, но компилятор жалуется на это.
Этот вопрос не совпадает с Trait, реализующим Sized .В этом вопросе параметр Foo
перемещается, поэтому обычно компилятор хочет знать его размер во время компиляции.В моем случае параметр является ссылкой, поэтому ему не требуется размер , но все же компилятор неявно предполагает, что это так, если явно не указано (с использованием + ?Sized
).Что бы я хотел изменить, так это неявное предположение, касающееся этой конкретной черты.