#cell #project #no-std

no-std cell-project

cell投影的安全接口

1个不稳定版本

0.1.4 2022年8月8日
0.1.3 2020年12月21日
0.1.2 2020年5月3日
0.1.1 2020年4月30日
0.1.0 2020年4月30日

#2516 in Rust模式

MIT许可证

8KB

cell-project

通过共享引用到core::cell::Cell的安全接口。

文档:https://docs.rs/cell-project

use std::cell::Cell;
use cell_project::cell_project as cp; // renamed for ergonomics

struct Point {
    x: f32,
    y: f32,
}

fn get_x_cell(point: &Cell<Point>) -> &Cell<f32> {
    cp!(Point, point.x)
}

宏的语法如下

let projection = cp!($TypeOfValue, $value_identifier.$field_identifier);

不允许为$value_identifier传递表达式,如果需要的话,你应该这样做。

let value = Cell::new(get_point());
let projection = cp!(Point, value.y);

如果您需要通过多个字段进行投影,则需要多次调用cp!,每次投影一次

struct Pair<T>(T, T);

// let some_pair: &Cell<Pair<Point>>;
let point = cp!(Pair<Point>, some_pair.0);
let x = cp!(Point, point.x);

注意:对于泛型类型,您可以使用_来推断泛型参数

fn get_x_cell<T>(point: &Cell<Pair<T>>) -> &Cell<T> {
    cp!(Pair<_>, point.0)
}

一些限制,您不能投影枚举变体,因为这可能是不可靠的。

let x = Cell::new(Some(0));

// let's imagine a macro like `try_cell_project`, which takes a varaint as well as a type
let proj = cell_project::try_cell_project!(Option<_>, Some, x.0).unwrap();

x.set(None); // we can still write to the `Cell` directly

// this will read uninitialized memory (because that's what `None` wrote in)
// and there is no way to fix this. Enums cannot allow safe projection through
// a shared mutable reference (like `&Cell<_>`)
let _ = proj.get();

因此,您不能通过枚举进行投影

稳定的另一个限制是,您只能投影到Sized类型。例如,如果我有一个类型

struct Unsized(i32, [u8]);

那么我只能投影到第一个字段,因为第二个字段是!Sized

特性

nightly - 解锁cell_project::nightly_cell_project,它使用不稳定的功能#![feature(raw_ref_op)],允许投影到!Sized字段。

许可证:MIT

无运行时依赖