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

Rust中是否有通用模式定义可持有或借用值的结构体?

Rust中通用结构体:同时支持持有值与借用值的方案探讨

本文探讨Rust编程中的一类通用问题:如何定义结构体,使其无需关心自身是持有还是借用某一值。

假设我们有结构体Foo,它需要访问&Bar来完成功能,初始定义如下:

struct Foo<'a> {
  bar: &'a Bar,
}

impl Foo<'_> {
  fn fulfill_purpose(&self) {
    let bar = self.bar;
    // 我们获得了&Bar的访问权 \o/
  }
}

但在不同场景下,获取Bar的方式不同,初始定义会遇到各种局限:

  • 若已在栈上持有Bar,可直接构造Foo,此时Foo的生命周期与bar一致:
    let bar = construct_bar();
    let foo = Foo { bar: &bar };
    // 此时Foo的生命周期与bar一致 \o/
    
  • 若从磁盘/网络等获取Bar并封装为工具函数返回Foo,当前定义会因生命周期问题无法返回:
    fn fetch_foo() -> Foo {
      let bar = fetch_bar();
      let foo = Foo { bar };
      // 错误!bar仅存在于函数作用域,无法返回foo
    }
    
  • 若将Foo改为持有Bar,则在共享Bar或使用全局Mutex包裹的Bar时又会遇到生命周期问题:
    static GLOBAL_BAR: Mutex<Bar>;
    
    fn global_foo() -> Foo {
      let bar = GLOBAL_BAR.lock();
      let foo = Foo { bar: &bar };
      // 错误!MutexGuard仅存在于函数作用域,无法返回foo
    }
    

为此尝试泛型方案,通过抽象一个能提供&Bar的类型参数来解决:

struct Foo<SomeBar> {
  bar: SomeBar,
}

impl<SomeBar: SomeTrait> Foo<SomeBar> {
  fn fulfill_purpose(&self) {
    // 假设SomeBar::as_bar(&self) -> &Bar
    let bar = self.bar.as_bar();
    // 我们获得了&Bar的访问权 \o/
  }
}

但标准库中的现有 trait 存在不足:

  • Deref和AsRef无针对T的 blanket 实现,无法直接支持Foo持有Bar的场景;
  • Borrow虽有 blanket 实现,但部分标准库类型(如std::cell::Ref)未实现该 trait,通用性不足。

本人尝试通过定义新类型Owned<T>配合Deref实现:

struct Owned<T>(T);

impl<T> Deref for Owned<T> {
  type Target = T;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}

struct Foo<SomeBar: Deref<Target=Bar>> {
  bar: SomeBar,
}

但该方案未在实际代码中见过,故询问:是否存在此类问题的通用解决方案?本人的思路是否存在根本性错误?

注:此问题与使用Cow运行时追踪所有权的方案不同,需通过泛型静态追踪所有权。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 00:07:31