在 Rust 范围内初始化变量的正确方法

Proper way to initialize variables inside scope in Rust

我是 Rust 新手,想写一些简单的游戏。

在下面的代码中,我在代码中定义了 2 个游戏玩家之间的猜谜者和猜谜者。

enum PlayerMovingPosition{
    Riddler,
    Guesser,
}

struct Player {
    name: String,
    moving_position: Option<PlayerMovingPosition>,
}

struct Game {
    player1: Player,
    player2: Player,
}

fn define_riddler_n_guesser(&self) {
    let mut riddler: &Player;
    let mut guesser: &Player;
    for player in [&self.player1, &self.player2] {
        match player.moving_position {
            Some(PlayerMovingPosition::Riddler) => riddler = player,
            Some(PlayerMovingPosition::Guesser) => guesser = player,
            _ => panic!("Hey damba, player {} moving position is undefined!", player.name.as_str()),
        }
    
    //... Place where I got the error
    }

我有 E0381 error,它说变量可能在那里被初始化。

我进行了一些搜索并得到了矛盾的答案,例如:

let lol;
{
    lol = "kek";
}
println!(lol);
// kek

我发现它有争议,我无法决定在我的情况下该怎么做,但我敢打赌它们并不矛盾,它们是关于不同的事情,而且由于理解不足,我看不出这种差异。

如果你告诉我我是否用 Rust 编写了糟糕的代码并告诉我正确的代码,那就太好了

您可以使用匹配模式解决此问题。 此匹配模式将确保 riddlerguesser 始终分配

        let (riddler, guesser) = match (&self.player1.moving_position, &self.player2.moving_position) {
            (Some(PlayerMovingPosition::Riddler), Some(PlayerMovingPosition::Guesser)) => (&mut self.player1, &mut self.player2),
            (Some(PlayerMovingPosition::Guesser), Some(PlayerMovingPosition::Riddler)) => (&mut self.player2, &mut self.player1),
            _ => panic!("Unsupported combo"),
        };

playground

以下是我的一些观察:

  • 看起来 define_riddler_n_guesserGame 结构的一个方法。如果是这样,则需要将其放入impl Game { ... }。在这种情况下,self 表示调用该方法的结构实例。
  • 如果玩家的字段moving_position不能None,则不需要使用Option
  • 关于变量初始化的两种观点对我来说都是正确的。变量未经初始化不能使用。

这里是根据以上几点修改的代码。仅供参考。

#[derive(PartialEq, Eq)]
enum PlayerMovingPosition{
    Riddler,
    Guesser,
}

struct Player {
    name: String,
    moving_position: PlayerMovingPosition,
}

struct Game {
    player1: Player,
    player2: Player,
}

impl Game {
    fn define_riddler_n_guesser(&mut self) {
        let (riddler, guesser) = 
            if self.player1.moving_position == PlayerMovingPosition::Riddler { 
                (&mut self.player1, &mut self.player2)
            } else {
                (&mut self.player2, &mut self.player1)
            };
    }
}

Playground

也许您可以采取稍微不同的方法:在游戏实例中保存玩家的角色。这将使交换角色更容易并修复你的错误(因为猜谜者和猜测者总是被定义)。

代码如下:

struct Player {
    name: String,
}

struct Game {
    player1: Player,
    player2: Player,
    player1_is_riddler: bool,
}

impl Game {
    fn define_riddler_n_guesser(&self) {
        let (riddler, guesser) = if self.player1_is_riddler {
            (&self.player1, &self.player2)
        } else {
            (&self.player2, &self.player1)
        };
        //... Place where you got the error
    }
}