请考虑以下几点

use std::sync::{Arc,Mutex};

fn arc_mutex_from_slice<T>(v: &[T]) -> Arc<Mutex<[T]>> {
    todo!();
}

fn main() {
    let v = vec![1,2,3];
    println!("{:#?}", arc_mutex_from_slice(&v[..]));
}

有没有可能实施arc_mutex_from_slice?可以为Arc<Mutex<Box<[T]>>>Arc<Mutex<Vec<T>>>实现此转换,但这两者都添加了另一个不必要的分配/间接.

类型Arc<Mutex<[T]>>是有效的,并且可以在片的大小已知时被初始化.

let x = Arc::new(Mutex::new([1,2,3]));

但当切片的大小未知时,我找不到任何方法来实现这一点.天真地try 实现arc_mutex_from_slice,如下所示不能编译.

fn arc_mutex_from_slice<T>(v: &[T]) -> Arc<Mutex<[T]>> {
    return Arc::new(Mutex::new(*v));
}
error[E0277]: the size for values of type `[T]` cannot be known at compilation time
 --> src/main.rs:4:21
  |
4 |     return Arc::new(Mutex::new(*v));
  |            -------- ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |            |
  |            required by a bound introduced by this call
  |
  = help: within `Mutex<[T]>`, the trait `Sized` is not implemented for `[T]`
  = note: required because it appears within the type `Mutex<[T]>`
note: required by a bound in `Arc::<T>::new`

有哪unsafe种魔法能帮上忙吗?

推荐答案

在编写本文时,对于Safe Rust,您可以这样做,但前提是在编译时知道发生分配时数组的大小:

let v: Arc<Mutex<[u8]>> = Arc::new(Mutex::new([0;16]));

这基本上是从Arc<Mutex<[u8;16]>>分到Arc<Mutex<[u8]>>分.

然而,目前还没有办法使用仅在运行时知道其大小的数组来安全地做到这一点.棘手的部分是,您需要创建未调整大小的Mutex<[u8]>并将其移动到Arc的构造函数,但移动值目前需要编译器知道它们的大小.

RFC 1909可能会对这种情况有所帮助,但自2017年以来一直开放,看不到结束的迹象.


至于unsafe……您可以分配一段既可以容纳Mutex<()>也可以容纳数组的内存,并通过字节偏移量手动访问它.不过,您必须小心--您可能需要在互斥锁和数组之间填充以满足数组元素的对齐,并确保您没有违反任何别名或约定规则.

Rust相关问答推荐

程序退出后只写入指定管道的数据

在自定义序列化程序中复制serde(With)的行为

在决定使用std::Sync::Mutex还是使用Tokio::Sync::Mutex时,操作系统线程调度是考虑因素吗?

闭包不会发送,即使它只捕获发送变量

当对VEC;U8>;使用serde_json时,Base64编码是保护空间的好方法吗?

对于已经被认为是未定义行为的相同数据,纯粹存在`&;[u32]`和`&;mut[u32]`吗?

正则表达式中的重叠匹配?(铁 rust 正则式发动机)

解析程序无法在Cargo 发布中 Select 依赖版本

为什么在 Allocator API 中 allocate() 使用 `[u8]` 而 deallocate 使用 `u8` ?

Rust:为什么 &str 不使用 Into

在 Rust 中查找向量中 dyn struct 的索引

为什么Rust中无法推断生命周期?

为什么需要同时为值和引用实现`From`?方法不应该自动解引用或borrow 吗?(2023-06-16)

从嵌入式 Rust 中的某个时刻开始经过的时间

`移动||异步移动{...}`,如何知道哪个移动正在移动哪个?

切片不能被 `usize` 索引?

Rust 将特性传递给依赖项

使用方法、关联函数和自由函数在 Rust 中初始化函数指针之间的区别

如何解析 Rust 中的 yaml 条件字段?

如何将切片推入数组?