#thread-local #thread-local-storage #inject #macro #local-storage #scoped-thread-local #scoped-tls

thread-scoped-ref

一个类似线程局部存储的库,但允许在作用域内存储引用/dyn Trait。

5 个版本

0.1.4 2020年4月24日
0.1.3 2020年4月24日
0.1.2 2020年4月23日
0.1.1 2020年4月23日
0.1.0 2020年4月23日

#888Rust 模式

MIT/Apache

16KB
121

thread_scoped_ref

一个类似线程局部存储的库,但允许在作用域内存储引用/dyn Trait。它可以用来将引用(如果你不拥有数据,且 Rc/Arc 不可能)注入到你完全无法控制的东西中(例如,你提供并由你无法拥有的库调用的函数)。

它与https://github.com/alexcrichton/scoped-tls也非常相似,但有以下区别

  • thread_scoped_ref 与特性和/非固定大小类型一起工作。
  • thread_scoped_ref 在调用 ScopedKey::with 时不会 panic,而是使用 None 调用闭包。

根据 scoped-tls,旧的标准库中曾经有过类似的东西(来自 scoped-tls 的引用)

一个 Rust 库,在 crates.io 上提供旧标准库的 scoped_thread_local! 宏作为库实现。

... 以及另一个似乎做同样事情(以及更多,如可变引用)的库 https://crates.io/crates/scoped-tls-hkt - 看起来我们几乎同时在这个工作上(scoped-tls-hkt 的作者上周发布了它;2020-04-18)。你绝对也应该看看那个。

示例用例

.
          +----- (set) ---------> &Data <------- (access/read) ----------+
          |                                                              |
+---------+------------+    +--------------------------------------------|-------------+
| Data                 |    | External library                           |             |
| (huge/context/no Rc) |    |                                            |             |
+----------------------+    |                                +-----------+------+      |
                            |              ---- (calls) ---> | Your function    |      |
                            |                                +------------------+      |
                            +----------------------------------------------------------+

更多信息

使用

Cargo

[dependencies]
thread-scoped-ref = "0"

示例

use thread_scoped_ref::{thread_scoped_ref, scoped, with};
use std::collections::HashMap;

thread_scoped_ref!(SOME_ENV_VALUES, HashMap<String, String>);

/// It's not possible to pass `&HashMap<String, String>` to this function since it's called
/// by some library you don't control...
fn read_env_value() {
  // ... so we read from the static 'SOME_ENV_VALUES'.
  with(&SOME_ENV_VALUES, |maybe_env_values| {
    // don't "unwrap" in reality: Since `maybe_env_values` will be `None` if not
    // called within a scope!
    let env_values = maybe_env_values.unwrap();
    assert_eq!("true", env_values.get("delete_entire_ssd").unwrap());
  });
}

 /// An external library you don't control or generated code.
fn external_library(function_ptr : fn()) {
   function_ptr();
}

let mut env_values = HashMap::default();
env_values.insert("delete_entire_ssd".to_string(), "true".to_string());
// Create a scope. Note: We only need a reference to `env_values` (no move required).
scoped(&SOME_ENV_VALUES, &env_values, || {
  external_library(read_env_value);
});

许可

许可如下之一

任选其一。

无运行时依赖