我正在使用实验性功能feature(struct_inherit)
。
我有LocalPlayer
和NetPlayer
结构,它们都实现Inputable
特征,并从虚拟结构player_num
继承Player
字段。根据游戏的开始方式,我的计划中的player_2
可以是LocalPlayer
或NetPlayer
。具体取决于哪一个,Inputable
特征的实施方式发生了变化。
编译器不允许我动态分配player_2
类型,具体取决于它是NetPlayer
还是LocalPlayer
。它抱怨道:
错误:不匹配的类型:期望
~player::LocalPlayer
但找到~player::NetPlayer
(预期的struct player :: LocalPlayer但找到struct player :: NetPlayer)
它还不允许我对NetPlayer
指针进行类型转换LocalPlayer
或Player
指针。它声称它们不具备可扩展性。
有问题的代码示例如下:
let player1 = box player::LocalPlayer::new(0);
let player2;
if local {
player2 = box player::LocalPlayer::new(1);
} else if hosting {
player2 = box player::NetPlayer::new(1);
player2.host();
} else {
player2 = box player::NetPlayer::new(1);
player2.connect();
}
/* ... Omitted Code ... */
let input = player2.get_input(); // Trait function
结构实现如下:
pub virtual struct Player {
player_num: uint
}
pub struct LocalPlayer: Player;
pub struct NetPlayer: Player;
答案 0 :(得分:5)
Rust中的结构继承非常原始;你可能不想使用它。在Rust中继承结构之间没有子类型或强制。如果你有很多具有类似字段的结构,这个功能基本上只允许你保存输入(它还可以为将来在它们周围添加更多功能而进行未来验证)。
您可以制作Player
,LocalPlayer
和NetPlayer
个特征。然后,您可以获得它们之间所需的子类型行为。或者,您可以只生成LocalPlayer
和NetPlayer
结构,让Player
成为特征。您甚至可以拥有一个PlayerImpl
结构,您可以从当前的方式继承该结构(如果您要分享很多字段),但是您需要为两个结构编写独立的impls。
答案 1 :(得分:4)
Rust的特征与接口类似,可以组成模拟接口层次结构。它们通常是继承的替代品:
trait GetInput {
fn get_input(&self);
}
impl GetInput for Player {
fn get_input(&self) {}
}
impl GetInput for NetPlayer {
fn get_input(&self) {}
}
// Fast: interface selected at compile time
fn do_something<T: GetInput>(player: T) {
player.get_input();
}
// Flexible: interface selected at run time (virtual call)
// Use with Box<Player> (see "Trait Objects")
fn do_something_dyn(player: &dyn GetInput) {
player.get_input();
}
但是,Rust没有继承数据。要在类型之间共享公共字段,您需要一些替代的DIY解决方案(例如特征中的getter / setter或带有枚举的结构)。
答案 2 :(得分:3)
我最终将Player
作为枚举实现:
pub enum Player {
Net(NetPlayer),
Local(LocalPlayer)
}
每次调用共享函数时,我都需要执行以下操作:
let input = match player2 {
player::Net(player) => player.get_input(),
player::Local(player) => player.get_input(),
};