问题描述
我有这个特点:
trait Pokemon {
type Move;
fn pick_move(&self) -> Self::Move;
}
某些类型实现了 trait,如下所示:
#[derive(PartialEq,Clone,copy)]
enum Fire {
Charmander,Charmeleon,Charizard
}
#[derive(PartialEq,copy)]
enum FireMove {
Ember,FlameThrower,FireBlast
}
#[derive(PartialEq,copy)]
enum Water {
Squirtle,Wartortle,Blastoise
}
#[derive(PartialEq,copy)]
enum WaterMove {
Bubble,WaterGun
}
impl Pokemon for Fire {
type Move = FireMove;
fn pick_move(&self) -> Self::Move {
match self {
Self::Charmander => Self::Move::Ember,Self::Charmeleon => Self::Move::FlameThrower,Self::Charizard => Self::Move::FireBlast,}
}
}
impl Pokemon for Water {
type Move = WaterMove;
fn pick_move(&self) -> Self::Move {
if *self == Water::Squirtle {
return Self::Move::Bubble;
}
Self::Move::WaterGun
}
}
对于实现了 Pokemon
trait 的类型,我想实现一个 trait Battle
:
trait Battle {
fn battle(&self) -> ??;
}
最后,我想要实现的是我应该能够在任何实现 .battle
特性的类型上调用 Pokemon
并最终能够返回赢得战斗。
我也考虑过使用这样的方法:
fn battle<T>(pokemon: T,foe: T) -> T
where T: Pokemon
{
let p_move = pokemon.pick_move();
let f_move = foe.pick_move();
if p_move == f_move {
return pokemon;
}
foe
}
很遗憾,在这里我无法比较已传递参数的 Move
。
我接近实现这一目标的一种方法是做这样的事情:
trait Battle {
type Pokemons;
fn battle(&self,foe: Self::Pokemons) -> Self::Pokemons;
}
#[derive(PartialEq,copy)]
enum PokemonTypes {
Fire(Fire),Water(Water),Grass(Grass)
}
impl Battle for Fire {
type Pokemons = PokemonTypes;
fn battle(&self,foe: Self::Pokemons) -> Self::Pokemons {
match foe {
Self::Pokemons::Water(pokemon) => Self::Pokemons::Water(pokemon),_ => Self::Pokemons::Fire(*self) // because Fire beats Grass type
}
}
}
所以基本上,我如何实现这个 Battle
特征,以帮助我比较动作和/或口袋妖怪类型并决定获胜者?
解决方法
您可以将移动类型抽象为另一个枚举,并删除特征中的关联类型:
postgres=> explain analyze select count(id) from application;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=1245180.18..1245180.19 rows=1 width=8) (actual time=311470.250..311496.933 rows=1 loops=1)
-> Gather (cost=1245179.96..1245180.17 rows=2 width=8) (actual time=311470.225..311496.919 rows=3 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial Aggregate (cost=1244179.96..1244179.97 rows=1 width=8) (actual time=311463.287..311463.289 rows=1 loops=3)
-> Parallel Seq Scan on application (cost=0.00..1234885.77 rows=3717677 width=16) (actual time=79.783..311296.505 rows=1202169 loops=3)
Planning Time: 0.083 ms
Execution Time: 311497.021 ms
(8 rows)
然后以同样的方式,您可以直接将您的实现用于 #[derive(PartialEq,Clone,Copy)]
enum Move {
Water(WaterMove),Fire(FireMove),}
trait Pokemon {
fn pick_move(&self) -> Move;
}
系统,但是实现对 Battle
的战斗:
PokemonType