#slice #macro #assign #set #编译时

无 std set_slice

用于给切片赋值的宏

12 个版本

使用旧的 Rust 2015

0.3.0 2018 年 7 月 18 日
0.2.10 2018 年 7 月 17 日

Rust 模式 中排名第 2300

每月下载量 32

Apache-2.0

19KB
222

set_slice

一个用于轻松给切片赋值的 Rust 宏

Latest version Documentation License

使用 set_slice 的规则

  1. 您只能使用切片,或者任何可以转换为切片的东西
  2. 左值必须是标识符或索引
    1. 标识符:数组,b,vector,其他
    2. 索引:array[1..],b[..],vector[1..4],其他[12..=14]
  3. 范围检查都是在运行时完成的
    1. 输入切片的大小必须与要分配的切片大小相同
  4. 类型必须匹配
    1. 注意:set_slice 使用内部泛型函数来确定类型信息
  5. 对于不安全的复制值,切片的大小必须在编译时已知,作为 constexpr
  6. 对于安全的引用赋值,内部类型必须是 Clone 或 Copy 以正常工作

通过示例说明 set_slice

您可以设置切片的全部内容为任何您想要的值

let slice = &mut [0; 3] as &mut [i32]; // this is to simulate having only a slice without knowning its size

set_slice! {
    slice = 1, 2, 3; // this list is internally counted and converted to an array at compile-time
}
assert_eq!(slice, [1, 2, 3]);

// ... or you can only set parts of the slice 
let slice = &mut [0; 5] as &mut [i32];

set_slice! {
    slice[..3] = 1, 2, 3;
}
assert_eq!(slice, [1, 2, 3, 0, 0]);

您也可以在一个宏调用中执行多个赋值

let slice = &mut [0; 5] as &mut [i32];

set_slice! {
    slice[..2] = 1, 2;
    slice[3..] = 4, 5;
}
assert_eq!(slice, [1, 2, 0, 4, 5]);

您可以使用表达式来设置切片,无论是作为要移动的值,还是作为引用(如果是移动值,您必须指定括号中的 const 表达式大小)

let slice = &mut [0; 5] as &mut [i32];
let array = [1, 2];
let vec = vec![3, 4];

set_slice! {
    slice[..2] = move array;
    slice[3..] = move vec;       // vec is moved into set_slice
}
println!("array = {:?}", array); // fine, array is a copy type
// println!("vec = {:?}", vec);  // compile time error, vec is moved into the set_slice and dropped
assert_eq!(slice, [1, 2, 0, 3, 4]);

但您不需要将引用移动到 set_slice,如果使用引用,您必须指定内容是否应该复制或克隆(但它们必须分别实现 Copy 或 Clone)

let slice = &mut [0; 5] as &mut [i32];
let array = [1, 2];
let vec = vec![3, 4];

set_slice! {
    slice[..2] = copy &array; // array is NOT moved into set_slice, and contents are copied
    slice[3..] = copy &vec;   // vec is NOT moved into set_slice, and contents are copied
}
println!("array = {:?}", array); // this is fine, array was borrowed
println!("vec = {:?}", vec); // this is fine, vec was borrowed
assert_eq!(slice, [1, 2, 0, 3, 4]);
#[derive(Clone, Debug, PartialEq)]
enum A { Zero, One };
let slice: [A; 5] = [A::Zero, A::Zero, A::Zero, A::Zero, A::Zero];
let slice = &mut slice as &mut [A];
let array = [A::One, A::One];
let vec = vec![A::One; 2];

set_slice! {
    slice[..2] = clone &array;   // array is NOT moved into set_slice, and contents are cloned
    slice[3..] = clone &vec;     // vec is NOT moved into set_slice, and contents are cloned
    // slice[3..] = copy &vec;   // this won't work because 'A' is not a copy type
}
println!("array = {:?}", array); // this is fine, array was borrowed
println!("vec = {:?}", vec);     // this is fine, vec was borrowed
assert_eq!(slice, [A::One, A::One, A::Zero, A::One, A::One]);

有效用例

与列表和范围一起使用

这些范围可以与其他子部分混合使用

let slice = &mut [0; 3] as &mut [i32];
let init = 1;
let end = 2;

set_slice! {
    slice = 1, 2, 3;
    slice[..] = 1, 2, 3;
    slice[0..] = 1, 2, 3;
    slice[..3] = 1, 2, 3;
    slice[0..3] = 1, 2, 3;
    slice[0..2] = 1, 2;
    slice[1..2] = 2;
    slice[init..2] = 2;
    slice[1..end] = 2;
    slice[init..end] = 2;
    slice[init..] = 2, 3;
    slice[..end] = 1, 2;
}

println!("{:?}", slice);
panic!();

与移动类型一起使用

let slice = &mut [0; 3] as &mut [i32];
let vec_move = vec![1, 2, 3];

set_slice! {
    slice = move vec_move;
}
let vec_move = vec![1, 2, 3];

set_slice! {
    slice[..] = move vec_move;
}
let vec_move = vec![1, 2];

set_slice! {
    slice[..2] = move vec_move;
}

与引用一起使用

let slice = &mut [0; 3] as &mut [i32];
let array = [1, 2, 3];
let vec = vec![1, 2, 3];

// only works if slice implements copy
set_slice! {
    slice = copy &vec;
    slice = copy &array;
    slice[..2] = copy &vec[1..];
    slice[..2] = copy &array[1..];
}

// only works if slice implements clone
set_slice! {
    slice = clone &vec;
    slice = clone &array;
    slice[..2] = clone &vec[1..];
    slice[..2] = clone &array[1..];
}

// works with any type, but is incredibly unsafe
set_slice! {
    unsafe slice: (3) = ref &vec;
    unsafe slice: (3) = ref &array;
    unsafe slice[..2]: (2) = ref &vec[1..];
    unsafe slice[..2]: (2) = ref &array[1..];
}

已知未定义的行为或意外行为

所有这些都是在使用不安全的切片赋值时发生的

  • Boxed 值数组在赋值后共享内部值
  • Mutex 数组可能会损坏
    • Arc 数组没问题

无运行时依赖