如何进行类型转换和继承Rust结构?

问题描述 投票:5回答:3

我正在使用实验性功能feature(struct_inherit)

我有LocalPlayerNetPlayer结构,他们都实现了Inputable特性以及从虚拟结构player_num继承Player字段。根据比赛开始的方式,我的节目中的player_2可以是LocalPlayerNetPlayer。取决于哪一个,Inputable特征的实施方式发生了变化。

编译器不会让我动态地为player_2指定一个类型,具体取决于它是NetPlayer还是LocalPlayer。它抱怨说:

错误:不匹配的类型:预期~player::LocalPlayer但找到~player::NetPlayer(预期的struct player :: LocalPlayer但找到struct player :: NetPlayer)

它也不会让我强调NetPlayerLocalPlayer指向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;
struct rust
3个回答
5
投票

Rust中的结构继承非常原始;你可能不想使用它。在Rust中继承结构之间没有子类型或强制。如果你有很多具有类似字段的结构,这个功能基本上只允许你保存输入(这也是未来可能在将来添加更多功能的未来证明)。

你可以制作PlayerLocalPlayerNetPlayer特质。然后,您可以获得它们之间所需的子类型行为。或者,你可以制作LocalPlayerNetPlayer结构,让Player成为一个特征。您甚至可以拥有一个PlayerImpl结构,您可以从当前的方式继承(如果您有很多字段要共享),但是您需要为两个结构编写独立的impls。


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或带有枚举的结构)。


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(),
};
© www.soinside.com 2019 - 2024. All rights reserved.