是否可以指定函数的Vec参数具有一定的长度?考虑骰子的可能值:
fn new(d_type: DiceType, face_vals: /*Vec<u32> with len() == 2/4/6/8/10/12/20*/) -> Dice {...}
Run Code Online (Sandbox Code Playgroud)
我正在写一些东西,可以让你创建一个具有指定面值的多面体骰子(通常的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
}
}
Run Code Online (Sandbox Code Playgroud)
回答
接受的答案显示了很好地利用结果返回一个值,但响应让我思考如何使代码更灵活,同时仍然有一个硬盘,可以保证单个卷的溢出安全性,所以我删除了一堆代码并提出以下内容,可让您生成每卷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,
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您应该使用具有固定长度的相应数组的变体的枚举:
#[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]),
}
Run Code Online (Sandbox Code Playgroud)
那么你不能有无效的价值:
fn take_a_dice(_dice: Dice) {
//
}
fn main() {
take_a_dice(Dice::D4([1, 2, 4, 8]));
}
Run Code Online (Sandbox Code Playgroud)