英文:
Rust: is there something like C99 designated range initializer for arrays?
问题
类似的问题在在Rust中是否有获取C99数组指定符或替代方案的方法?中提出过,但那里的答案不能为给定的范围初始化一个值。
例如,
int a[10] = { [4 ... 8] = 10 };
Rust中的常量数组如何在范围上使用初始化程序?如果我们不使用const
,可以通过fill()
方法完成:
let mut a: [i32; 10] = [0; 10];
a[4..9].fill(10);
但fill()
无法在const
块中使用。
英文:
The similar question is asked in Is there a way to get C99 array designators or alternative in Rust?, but the answers there cannot initialize a value for a give range.
For example,
int a[10] = { [4 ... 8] = 10 };
How do const arrays in Rust use an initializer on the range? If we don't use const
, it can be done by fill()
method:
let mut a: [i32; 10] = [0; 10];
a[4..9].fill(10);
But fill()
cannot be used in const
block.
答案1
得分: 4
没有内置的方法来完成这个,但可以使用宏自己创建它:
macro_rules! array_ranged_init {
( $default_value:expr $(, $($min:literal)? .. $($max:literal)? = $value:expr)* ; $len:expr ) => {
{
let mut array = [$default_value; $len];
$(
#[allow(unused_variables)]
let min = 0;
$(let min = $min;)?
#[allow(unused_variables)]
let max = $len;
$(let max = $max;)?
let mut i = min;
while i < max {
array[i] = $value;
i += 1;
}
)*
array
}
}
}
然后你可以像这样使用这个宏:
static DATA: [i32; 10] = array_ranged_init![0, 4..9 = 10; 10];
#[test]
fn test() {
assert_eq!(DATA, [0, 0, 0, 0, 10, 10, 10, 10, 10, 0])
}
这个宏允许你包含多个范围:
static DATA: [i32; 12] = array_ranged_init![
0,
1..6 = 4,
10.. = 6,
..1 = 1;
12
];
#[test]
fn test() {
assert_eq!(DATA, [1, 4, 4, 4, 4, 4, 0, 0, 0, 0, 6, 6])
}
英文:
There is no built-in way to do this, but it's possible to create it yourself with a macro:
macro_rules! array_ranged_init {
( $default_value:expr $(, $($min:literal)? .. $($max:literal)? = $value:expr)* ; $len:expr ) => {
{
let mut array = [$default_value; $len];
$(
#[allow(unused_variables)]
let min = 0;
$(let min = $min;)?
#[allow(unused_variables)]
let max = $len;
$(let max = $max;)?
let mut i = min;
while i < max {
array[i] = $value;
i += 1;
}
)*
array
}
}
}
You can then use the macro like this:
static DATA: [i32; 10] = array_ranged_init![0, 4..9 = 10; 10];
#[test]
fn test() {
assert_eq!(DATA, [0, 0, 0, 0, 10, 10, 10, 10, 10, 0])
}
This macro allows you to include multiple ranges:
static DATA: [i32; 12] = array_ranged_init![
0,
1..6 = 4,
10.. = 6,
..1 = 1;
12
];
#[test]
fn test() {
assert_eq!(DATA, [1, 4, 4, 4, 4, 4, 0, 0, 0, 0, 6, 6])
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论