Здравствуйте, so5team, Вы писали:
S>Можно узнать как? Без сарказма, реально интересно.
В расте можно написать просто метод для класса, а можно написать метод для класса для реализации интерфейса.
То есть если есть
trait Fooble {
fn foo(&self) {
println!("default Fooble::foo");
}
}
И просто структура
struct S {}
impl S {
fn foo(&self) {
println!("S::foo");
}
}
То это ты просто написал метод класса не имеющий отношения к интерфейсу. И если в коде есть
fn make_foo(f: &impl Fooble) { ...
То эту свою S туда не подсунешь
Но если ты прямо сказал что не просто пишешь foo а именно реализуешь метод интерфейса то можно так:
impl Fooble for S {
fn foo(&self) {
println!("S::foo");
}
}
То это ты уже реализовал интерфейс причем с перегрузкой. Соответсвенно если в разных интерфейсах есть методы с одним именем то ты можешь перегрузить этот метод для разных интерфейсов.
impl Fooble1 for S {
fn foo(&self) {
println!("S::foo for Fooble1");
}
}
impl Fooble2 for S {
fn foo(&self) {
println!("S::foo for Fooble2");
}
}
Заметь что при объявлении структуры я нигде не пишу каким интерфейсам она соответствует. Ты можешь вообще придумать свой интерфейс и написать реализацию любого типа (даже i32) для этого интерфейса. И этот интерфейс можно будет использовать динамически! При этом i32 это по-прежнему 32-битное число без лишних полей с vtbl_ptr которое в структурах и массивах хранится плотно без лишних байтов
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте