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

Rust中访问结构体字段时如何解决部分移动错误?

解决Rust中Solana ClientError的部分移动错误

问题场景

你的ClientError结构体定义如下:

#[derive(Error, Debug)]
#[error("{kind}")]
pub struct ClientError {
    pub request: Option<rpc_request::RpcRequest>,

    #[source]
    pub kind: ClientErrorKind,
}

在处理错误时的代码触发了部分移动错误:

Err(err: ClientError) => {
  if let MyError(myError) = err.kind {
    // 处理myError的逻辑
  }

  return Err(custom_error(err, ...));
}

错误信息:

use of partially moved value: `err`
partial move occurs because value has type `CustomType`, which does not implement the `Copy` trait

解决方案

方法1:通过引用匹配避免移动所有权

在模式匹配中使用ref关键字,仅获取err.kind的引用而非所有权,这样整个err的所有权不会被拆分,后续仍能完整使用:

Err(err) => {
  if let MyError(ref myError) = err.kind {
    // 这里使用myError的引用处理逻辑,不会移动err的任何字段
  }

  return Err(custom_error(err, ...)); // 此时err仍完整可用
}

如果你的Rust版本支持,也可以直接匹配引用:

Err(err) => {
  if let &MyError(ref myError) = &err.kind {
    // 同样通过引用访问myError
  }

  return Err(custom_error(err, ...));
}

方法2:解构后重组(需获取所有权时)

如果必须获取myError的所有权,可先将ClientError解构为各个字段,处理完成后再将剩余字段重新组装为ClientError传给custom_error:

Err(ClientError { request, kind }) => {
  match kind {
    MyError(myError) => {
      // 这里拥有myError的所有权,可自由处理
    }
    other_kind => {
      // 处理其他错误类型的逻辑
    }
  }

  // 重新组装ClientError,根据实际情况补充kind字段
  return Err(custom_error(ClientError {
    request,
    kind: // 提供合适的ClientErrorKind值
  }, ...));
}

方法3:为ClientErrorKind添加访问方法

如果不想在匹配时写ref,可以给ClientErrorKind枚举添加方法来返回内部值的引用:

impl ClientErrorKind {
    pub fn as_my_error(&self) -> Option<&CustomType> {
        match self {
            Self::MyError(e) => Some(e),
            _ => None,
        }
    }
}

然后在错误处理中这样使用:

Err(err) => {
  if let Some(myError) = err.kind.as_my_error() {
    // 使用myError的引用处理逻辑
  }

  return Err(custom_error(err, ...));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 19:15:31