gpt4 book ai didi

rust - 如何确保我的函数将收到有效长度的 Vec?

转载 作者:行者123 更新时间:2023-11-29 08:10:05 25 4
gpt4 key购买 nike

是否可以指定函数的 Vec 参数具有特定长度?考虑一个骰子的可能值:

fn new(d_type: DiceType, face_vals: /*Vec<u32> with len() == 2/4/6/8/10/12/20*/) -> Dice {...}

我正在写一些东西,让您可以创建一个具有指定面值的多面体骰子(通常的 RPG 大小:2、4、6 等)。我记得当你调用一个没有 unsafe 关键字的 Rust 函数时,用户应该能够以他们喜欢的方式调用它而不用担心失败,所以只需检查函数的有效性并返回一些 "你搞砸了” 错误是糟糕的 Rust。

我怎样才能做到这一点?

这是我正在处理的代码的一部分:

pub enum DiceType {
D2,
D4,
D6,
D8,
D10,
D10P,
D12,
D20,
}

pub struct Dice {
dice_type: DiceType,
face_count: usize,
face_values: Vec<u32>,
}

impl Dice {
pub fn new(d_type: DiceType, face_vals: Vec<u32>) -> Dice {
let mut retval;

//Reject if not a valid dice type 2, 4, 6, 8, 10, 12, or 20
//I really shouldn't be doing this should I?
if Dice::valid_dice(d_type, face_vals) {
retval = Dice {
dice_type: d_type,
face_count: face_vals.len(),
face_values: face_vals,
}
} else {
//User wont know they got an error
//Really shouldn't need to go here. How do I avoid needing
//error checking?
retval = Dice {
dice_type: None,
face_count: 2,
face_values: face_vals,
};
}

retval
}
}

回答

接受的答案显示了对结果返回值的良好使用,但响应让我思考如何使代码更灵活,同时仍然有一个硬帽可以保证单卷的溢出安全,所以我删掉了一个一堆代码并提出以下内容,它应该可以让您生成每卷 1-10,000 之间的任何骰子掷骰,并带有用于额外掷骰的乘数。

const MAX_FACE_VALUE: u32 = 100000;
const MAX_FACE_COUNT: u32 = 10000;
const MAX_ROLL_COUNT: u32 = 9999;

pub struct Dice {
face_count: usize,
face_values: Vec<u32>,
}

impl Dice {
pub fn new(mut face_vals: Vec<u32>) -> Self {
//User may not have values greater than 100,000
//Index access is safe since we use the for _ in _
for x in 0..face_vals.len() {
if face_vals[x] > MAX_FACE_VALUE {
//Enforce the limit
face_vals[x] = MAX_FACE_VALUE;
}
}

//User may not have more than 10,000 faces
if face_vals.len() > MAX_FACE_COUNT as usize {
let new_vals: Vec<u32> = face_vals.split_off(MAX_FACE_COUNT as usize);
Dice {
face_count: MAX_FACE_COUNT as usize,
face_values: new_vals,
}
} else if face_vals.len() == 0 {
//No 0 sided dice allowed
Dice {
face_count: 1,
face_values: vec![1],
}
} else {
//Normal range
Dice {
face_count: face_vals.len(),
face_values: face_vals,
}
}
}
}

最佳答案

您应该使用具有变体的枚举以及相应的固定长度数组:

#[derive(Clone, Copy)]
pub enum Dice {
D2([u32; 2]),
D4([u32; 4]),
D6([u32; 6]),
D8([u32; 8]),
D10([u32; 10]),
D10P([u32; 10]),
D12([u32; 12]),
D20([u32; 20]),
}

那么你不能有无效的值:

fn take_a_dice(_dice: Dice) {
//
}

fn main() {
take_a_dice(Dice::D4([1, 2, 4, 8]));
}

关于rust - 如何确保我的函数将收到有效长度的 Vec?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51493563/

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