Rust,相同类型,来自同一模块的不同导入的不同路径

AV_*_*LON 1 oop rust

我是 Rust 的新手,并且已经通过编写我的第一个玩具程序获得了一些方法,只是一个纸牌游戏实现。这是我当前的文件结构:

??? Cargo.lock
??? Cargo.toml
??? src
?   ??? card.rs
?   ??? deck.rs
?   ??? hand.rs
?   ??? main.rs
Run Code Online (Sandbox Code Playgroud)

基本构建块当然是卡片结构,它看起来像这样:

pub struct Card {
    value: Value,
    suit: Suit,
    is_visible : bool
}

impl Card {
    pub fn new(value: &Value, suit: &Suit) -> Card {
        Card {...}
    }
}
#[derive(Clone)]
pub enum Suit {...}
#[derive(Clone)]
pub enum Value{...}
Run Code Online (Sandbox Code Playgroud)

在deck.rs 中的deck 实现,使用card 模块:

#[path="card.rs"]
mod card;
pub use card::*;

pub struct Deck(Vec<Card>);

impl Deck {
    pub fn new(n_packs: u32) -> Deck {
        let mut cards = Vec::new();
        ...
        Deck(cards)
    }
    pub fn deal_from_top(&mut self, n_cards: u32) -> Vec<Card>{...}
    pub fn shuffle(&mut self) {...}

    ...
}
Run Code Online (Sandbox Code Playgroud)

非常相似的结构,Hand 在模块 hand.rs 中定义

#[path = "card.rs"]
mod card;
pub use card::*;

pub struct Hand(Vec<Card>);

impl Hand{
    pub fn new(cards: Vec<Card>) -> Hand{
        Hand(cards)
    }
}
Run Code Online (Sandbox Code Playgroud)

在 main.rs 中,我想

  • 创建一个甲板,
  • 洗牌,
  • 处理n张牌,
  • 将这些卡片放入手牌结构中

最后一个让我感到非常悲伤。

这是我尝试过的:

mod hand;
mod deck;
use hand::Hand;
use deck::Deck;

fn main() { 
    let mut deck = Deck::new(1);
    deck.shuffle();
    let mut cards = deck.deal_from_top(5);
    let mut hand = Hand::new(cards);
}
Run Code Online (Sandbox Code Playgroud)

这会引发编译时错误 E0308:

error[E0308]: mismatched types
  --> src/main.rs:13:30
   |
13 |     let mut hand = Hand::new(cards);
   |                              ^^^^^ expected struct `hand::card::Card`, found struct `deck::card::Card`
   |
   = note: expected struct `std::vec::Vec<hand::card::Card>`
              found struct `std::vec::Vec<deck::card::Card>`
Run Code Online (Sandbox Code Playgroud)

很明显,我在理解用户定义的类型如何“导入”以供使用时缺少一些东西。

通过导入卡模块,就主要而言,甲板使用的“卡​​”类型和手动成为单独的类型。我不希望deck 或hand 相互引用以访问相同命名空间版本的Card。

在这种情况下,如何使卡片结构完全可重用?还是我的某种面向对象的方法是如此广泛以至于无法在惯用的 Rust 中实现?到目前为止搜索一无所获,因此感谢任何帮助。

C。

pro*_*-fh 5

#[path="card.rs"]您强制您的deck和模块在非标准位置hand查找card 模块。在deck.rsand 中hand.rs,写作mod card;card视为前两个的模块。理论上,这些子模块应该位于src/deck/card.rs和 中src/hand/card.rs,因此path=可以在另一个地方找到这些子模块。

取而代之的是,您可能希望使用card处于同一级别的模块。只需删除mod card;这两个文件并写入pub use super::card::*;而不是pub use::card::*;. 最后,添加mod card;进去,main.rs以便main.rs在编译器读取时发现它。

在您的解决方案中,为两个不同的子模块重用相同的文件只是一个相当于复制/粘贴的技巧,但从语言的角度来看,这两个子模块和它们提供的结构是不同的(如编译器在错误消息中所述) .