如何在另一个once_cell::sync::Lazy 中使用once_cell::sync::Lazy?

lin*_*bin 3 synchronization lazy-initialization rust

我想使用Rust和once_cell来实现一些静态const结构实例,并且一个静态const向量包含这些静态结构实例。

这是示例代码:

use once_cell::sync::Lazy;

pub struct Kind {
  name: String,
  value: i32,
}

impl Kind {
  pub fn new(name: &str, value: i32) -> Kind {
    Kind {name: String::from(name), value}
  }
}

const HYBRID: Lazy<Kind> = Lazy::new(|| Kind::new("a", 1));
const BOND: Lazy<Kind> = Lazy::new(|| Kind::new("b", 2));
// other instances

static KINDS: Lazy<Vec<Kind>> = Lazy::new(|| {
  vec![
    HYBRID,
    BOND,
    // other instances,
  ]
});
Run Code Online (Sandbox Code Playgroud)

这是编译器错误:

use once_cell::sync::Lazy;

pub struct Kind {
  name: String,
  value: i32,
}

impl Kind {
  pub fn new(name: &str, value: i32) -> Kind {
    Kind {name: String::from(name), value}
  }
}

const HYBRID: Lazy<Kind> = Lazy::new(|| Kind::new("a", 1));
const BOND: Lazy<Kind> = Lazy::new(|| Kind::new("b", 2));
// other instances

static KINDS: Lazy<Vec<Kind>> = Lazy::new(|| {
  vec![
    HYBRID,
    BOND,
    // other instances,
  ]
});
Run Code Online (Sandbox Code Playgroud)

我该如何获得真正的Kind内部Lazy

Cha*_*man 6

一种选择是在那里创建它们:

static KINDS: Lazy<Vec<Kind>> = Lazy::new(|| {
    vec![
        Kind::new("a", 1),
        Kind::new("b", 2),
        // other instances,
    ]
});
Run Code Online (Sandbox Code Playgroud)

但上述方法不允许您使用它们的静态来单独使用这些值。如果您确实想这样做,则可以存储引用(请注意,您应该使用static而不是const值,请参阅常量和静态变量之间的区别是什么以及我应该选择哪个?)。由于Lazyimpls Deref,您可以只使用&*. Lazy::force()或者,如果您想更明确,也可以使用。

static HYBRID: Lazy<Kind> = Lazy::new(|| Kind::new("a", 1));
static BOND: Lazy<Kind> = Lazy::new(|| Kind::new("b", 2));
// other instances

static KINDS: Lazy<Vec<&Kind>> = Lazy::new(|| {
    vec![
        Lazy::force(&HYBRID),
        &*BOND,
        // other instances,
    ]
});
Run Code Online (Sandbox Code Playgroud)

或者,如果您需要拥有的值,请克隆它们:

#[derive(Clone)]
pub struct Kind { /* ... */ }

static HYBRID: Lazy<Kind> = Lazy::new(|| Kind::new("a", 1));
static BOND: Lazy<Kind> = Lazy::new(|| Kind::new("b", 2));
// other instances

static KINDS: Lazy<Vec<Kind>> = Lazy::new(|| {
    vec![
        HYBRID.clone(),
        BOND.clone(),
        // other instances,
    ]
});
Run Code Online (Sandbox Code Playgroud)