为啥在多个文件中使用结构时会出现“预期的结构文件 1::A 找到结构文件 2::A”错误?

Posted

技术标签:

【中文标题】为啥在多个文件中使用结构时会出现“预期的结构文件 1::A 找到结构文件 2::A”错误?【英文标题】:Why do I get "expected struct file1::A found struct file2::A" error when using a struct in multiple files?为什么在多个文件中使用结构时会出现“预期的结构文件 1::A 找到结构文件 2::A”错误? 【发布时间】:2021-10-25 22:44:14 【问题描述】:

我正在尝试在两个文件之间共享一个结构,但出现错误。

我有以下文件夹结构:

src/
  Models/
    Login.rs
  Routes/
    LoginRoute.rs
  Services/
    LoginService.rs
  main.rs

Login.rs 我有:

#[derive(Serialize, Deserialize, Debug)]
pub struct UserLoginResponse  
    id: i32, 
    username: String, 
    token: String

LoginRoute.rs 我有:

#[path = "../Models/Login.rs"]
pub mod Login;

#[path = "../Services/LoginService.rs"]
pub mod LoginService;

#[post("/login", format = "application/json", data = "<user>")]
pub async fn login(user: String) -> Json<Login::UserLoginResponse>       
     
    if let Ok(sk) = LoginService::callAuthenticate(user).await        
       return sk
......

LoginService.rs 我有:

#[path = "../Models/Login.rs"]
pub mod Login;

pub async fn callAuthenticate(user: String)->  Result<Json<Login::UserLoginResponse>, Error> 
...
let userLoginResponse :Login::UserLoginResponse = Login::UserLoginResponse::new(1,  "admin".to_string(), api_reponse.return_result); 
    Ok(Json(userLoginResponse))

我在return sk 行的LoginRoute.rs 中遇到错误:

expected struct 'LoginRoute::Login::UserLoginResponse', found struct 'LoginService::Login:UserLoginResponse'

【问题讨论】:

您为什么选择在您的mod 语句中使用#[path ... 因为它们不在同一个文件夹中 如果我可以问,您是从哪里了解到#[path] 属性的?如果这是在 Stack Overflow 上,似乎有些人可能会对添加一个不鼓励使用它的友好注释感兴趣。 @Jason lol 不太确定我在哪里学到的,可能是在其他地方,我现在知道得更好了 :) 【参考方案1】:

请不要将#[path = ...] 属性用于您的典型组织;它应该只用于晦涩难懂的情况。每次您执行mod something 时,您都在声明一个新模块。即使两个模块由于#[path = ...]而指向同一个文件,它们也会不同。

所以你声明了多个 UserLoginResponse 结构:

一个crate::LoginRoute::Login::UserLoginResponse 一个crate::LoginService::Login:UserLoginResponse 如果您还在main.rs 中声明了Login,也许还有另一个。

由于它们位于不同的模块中,Rust 编译器将它们视为不同的类型,这不是你想要的。

只需使用声明模块的惯用方式即可。如果您想保留现有的文件夹结构而没有中间的 mod.rs 文件,您可以在 main.rs 中声明它们,如下所示:

mod Models 
    pub mod Login;

mod Routes 
    pub mod LoginRoute;

mod Services 
    pub mod LoginService;

然后通过crate::Models::Login 之类的其他地方访问它们。

见:

How do I import from a sibling module?

您可能已经遇到了试图鼓励特定样式的编译器的警告:"module [...] should have a snake case name"。惯用的文件结构通常如下所示:

src/
  models/
    login.rs
    mod.rs
  routes/
    login_route.rs
    mod.rs
  services/
    login_service.rs
    mod.rs
  main.rs

main.rs 的位置:

mod models;
mod routes;
mod services;

src/models/mod.rs(例如)会有:

pub mod login;

【讨论】:

您好,感谢您的回答,我还是 Rust 的新手。我现在了解错误,尝试实施答案,我有一个问题,使用 mod.rs 是否有好处,这些文件夹将有几个文件,我还修复了命名约定以遵循蛇案例。谢谢 @Gonzalo “使用 mod.rs 有什么好处吗?” - 它主要是约定俗成的。你可以按照我提到的第一种方式来做,但是随着你的模块结构变得更深,它会变得笨拙。让这些中间文件将共享逻辑放在一组文件中通常很方便。 它还可以更轻松地在另一个项目中重用模块(或将其提取到自己的 crate):只需复制文件夹并将单个 mod 声明添加到您的 main.rs/@ 987654342@.

以上是关于为啥在多个文件中使用结构时会出现“预期的结构文件 1::A 找到结构文件 2::A”错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 SingleAsync 时会出现此错误?

为啥我在写C语言的头文件,编译时会出现重新定义变量的情况?

为啥在控制台应用程序中使用 CommonOpenFileDialog 时会出现此异常?

为啥在使用模板时会出现“未解析的外部符号”错误? [复制]

Django:为啥当我在 django 中通过 popen 使用 Ghostscript 时会出现“找不到文件”错误

为啥在将 malloc() 的指针分配给 char* 时会出现段错误?