You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust点路径访问serde反序列化结构体时类型不匹配报错解决

问题描述

基础定义

将反序列化得到的JSON数据映射为Rust结构体,示例JSON与对应结构体定义如下:

示例JSON:

{
   "infos": {
       "info_example": {
           "title": {
               "en": "Title for example",
               "fr": "Titre pour l'exemple"
           },
           "message": {
               "en": "Message for example"
           }
       }    
   },
   "errors": {}
}

对应Rust结构体定义(基于serde实现反序列化):

#[derive(Debug, Deserialize)]
struct Logs {
    infos: Infos,
    errors: Errors,
}

#[derive(Debug, Deserialize)]
struct Infos {
    info_example: Log,
}

#[derive(Debug, Deserialize)]
struct Errors {}

#[derive(Debug, Deserialize)]
struct Log {
    title: MultiString,
    message: MultiString,
}

#[derive(Debug, Deserialize)]
struct MultiString {
   en: String,
   fr: Option<String>,
   de: Option<String>
}

目标功能

期望实现一个支持点分隔路径字符串访问任意嵌套字段的方法,调用形式如下:

logs_manager.get("infos.info_example.message.en")

初始实现与报错

初始编写的LogsManager代码如下:

struct LogsManager {
    logs: Logs
}

impl LogsManager {
    fn get<T>(&self, element: &str) -> &T {
        let splitted: Vec<&str> = element.split(".").collect();

        // 后续将改为循环遍历完整路径,当前仅处理路径第一段做测试
        match splitted[0] {
            "infos" => {
                &self.logs.infos
            },
            "errors" => {
                &self.logs.errors
            }
            _ => panic!()
        }
    }
}

编译时触发E0308类型不匹配错误:

Compiling so_question_return_type v0.1.0 (/run/media/anton/data120/Documents/testa)
error[E0308]: mismatched types
  --> src/main.rs:26:17
   |
20 |     fn get<T>(&self, element: &str) -> &T {
   |            - this type parameter       -- expected `&T` because of return type
...
26 |                 &self.logs.infos
   |                 ^^^^^^^^^^^^^^^^ expected type parameter `T`, found struct `Infos`
   |
   = note: expected reference `&T`
              found reference `&Infos`

error[E0308]: mismatched types
  --> src/main.rs:29:17
   |
20 |     fn get<T>(&self, element: &str) -> &T {
   |            - this type parameter       -- expected `&T` because of return type
...
29 |                 &self.logs.errors
   |                 ^^^^^^^^^^^^^^^^^ expected type parameter `T`, found struct `Errors`
   |
   = note: expected reference `&T`
              found reference `&Errors`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `so_question_return_type` due to 2 previous errors

尝试的解决方案与新问题

为解决返回类型不统一的问题,尝试定义枚举包装所有可能的返回类型:

enum LogObject<'a> {
    Logs(&'a Logs),
    Infos(&'a Infos),
    Errors(&'a Errors),
    Log(&'a Log),
    MultiString(&'a MultiString)
}

将返回对象包装为LogObject枚举变体后代码可以通过编译,示例代码如下:

"infos" => {
    LogObject::Infos(&self.logs.infos)
}

为了便捷取出枚举中包装的内部对象,尝试实现泛型取值方法:

impl<'a> LogObject<'a> {
    fn retrieve_object<T>(&self) -> &T {
        match *self {
            Self::Logs(object) => object,
            Self::Infos(object) => object,
            Self::Errors(object) => object,
            Self::Log(object) => object,
            Self::MultiString(object) => object,
        }
    }
}

该实现再次触发编译错误:

error[E0308]: mismatched types
  --> crates/strings/src/manager.rs:63:44
   |
61 |     fn retrieve_object<T>(&self) -> &T {
   |                        -            -- expected `&T` because of return type
   |                        |
   |                        this type parameter
62 |         match *self {
63 |             Self::Logs(object) => object,
   |                                   ^^^^^^ expected type parameter `T`, found struct `structured::Logs`
   |
   = note: expected reference `&T`
              found reference `&structured::Logs`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `strings` due to previous error

尝试多种方案均无法解决问题,现咨询可行的实现方式。


内容的提问来源于stack exchange,提问作者antoninhrlt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 15:30:53