У тебя проблема не в трейтах, а в том что ты пытаешься обращаться к полям структуры, которая передаётся как T.
Решить эту проблему можно добавлением ещё одного трейта и ограничением женерика.
Вот так должно работать:
pub struct Animal {
pub name: String,
pub age: i32,
pub strength: i32,
}
pub struct Person {
pub name: String,
pub age: i32,
pub strength: i32,
}
// Выделяем новый трейт, который позволяет получить силу
trait Strength {
fn strength(&self) -> i32;
}
trait BaseTrait {
fn init(&self);
// В старом трейте принимаем target по ссылке и ограничиваем, что принимаем только такой target, который реализует trait Strength
fn stronger_than<T>(&self, target: &T) -> bool
where
T: Strength;
}
impl Strength for Person {
fn strength(&self) -> i32 {
self.strength
}
}
impl Strength for Animal {
fn strength(&self) -> i32 {
self.strength
}
}
impl BaseTrait for Person {
fn init(&self) {
println!("Hello, im Person: {}", self.name);
}
fn stronger_than<T>(&self, enemy: &T) -> bool
where
T: Strength,
{
self.strength > enemy.strength() // вызываем метод, вместо обращения к полю
}
}
impl BaseTrait for Animal {
fn init(&self) {
println!("Hello, im Animal: {}", self.name);
}
fn stronger_than<T>(&self, enemy: &T) -> bool
where
T: Strength,
{
self.strength > enemy.strength()
}
}
fn main() {
let person = Person {
name: String::from("John"),
age: 25,
strength: 12,
};
let animal = Animal {
name: String::from("Elephant"),
age: 5,
strength: 360,
};
person.init();
animal.init();
if person.stronger_than(&animal) {
println!("Person is stronger than animal");
}
if animal.stronger_than(&person) {
println!("Animal is stronger than person")
}
}
Либо можно вынести функцию stronget_that в отдельный трейт и реализовать его для каждого T, по аналогии с ответом
Василий Дёмин, но тогда реализаций придётся писать целую гору.