gpt4 book ai didi

rust - 如何使用常量泛型创建固定大小的字符串数组?

转载 作者:行者123 更新时间:2023-12-03 11:29:48 24 4
gpt4 key购买 nike

我有一个使用常量泛型的函数:

fn foo<const S: usize>() -> Vec<[String; S]> {
// Some code
let mut row: [String; S] = Default::default(); //It sucks because of default arrays are specified up to 32 only
// Some code
}
如何创建 String 的固定大小数组在我的情况下? let mut row: [String; S] = ["".to_string(), S];不起作用,因为 String没有实现 Copy特征。

最佳答案

你可以用 MaybeUninit unsafe 做到这一点:

use std::mem::MaybeUninit;

fn foo<const S: usize>() -> Vec<[String; S]> {
// Some code

let mut row: [String; S] = unsafe {
let mut result = MaybeUninit::uninit();
let start = result.as_mut_ptr() as *mut String;

for pos in 0 .. S {
// SAFETY: safe because loop ensures `start.add(pos)`
// is always on an array element, of type String
start.add(pos).write(String::new());
}

// SAFETY: safe because loop ensures entire array
// has been manually initialised
result.assume_init()
};

// Some code

todo!()
}
当然,将此类逻辑抽象为您自己的特征可能更容易:
use std::mem::MaybeUninit;

trait DefaultArray {
fn default_array() -> Self;
}

impl<T: Default, const S: usize> DefaultArray for [T; S] {
fn default_array() -> Self {
let mut result = MaybeUninit::uninit();
let start = result.as_mut_ptr() as *mut T;

unsafe {
for pos in 0 .. S {
// SAFETY: safe because loop ensures `start.add(pos)`
// is always on an array element, of type T
start.add(pos).write(T::default());
}

// SAFETY: safe because loop ensures entire array
// has been manually initialised
result.assume_init()
}
}
}
(使用您自己的 trait 而不是 Default 的唯一原因是后者的实现会与标准库中提供的最多 32 个元素的数组相冲突;我完全希望标准库用类似的东西替换 Default 的实现一旦const泛型稳定下来,就到上面了)。
在这种情况下,您现在将拥有:
fn foo<const S: usize>() -> Vec<[String; S]> {
// Some code

let mut row: [String; S] = DefaultArray::default_array();

// Some code

todo!()
}
Playground 上看到它。

关于rust - 如何使用常量泛型创建固定大小的字符串数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63450373/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com