Macros 如何避免在Rust中使用宏重复扩展索引?

Macros 如何避免在Rust中使用宏重复扩展索引?,macros,rust,Macros,Rust,是否有一种编写此宏的方法可以扩展数组访问,从而可以以不太冗长的方式编写较大的数组 /// Avoid manually expanding an expression, eg: /// /// let array = unpack!([some.vec; 3]); /// /// Expands into: [some.vec[0], some.vec[1], some.vec[2]] /// /// Supports expanding into different bracket type

是否有一种编写此宏的方法可以扩展数组访问,从而可以以不太冗长的方式编写较大的数组

/// Avoid manually expanding an expression, eg:
///
/// let array =  unpack!([some.vec; 3]);
///
/// Expands into: [some.vec[0], some.vec[1], some.vec[2]]
///
/// Supports expanding into different bracket types based on the input args.

macro_rules! unpack {
    ([$v_:expr; 2]) => { { let v = $v_; [v[0], v[1]] } };
    (($v_:expr; 2)) => { { let v = $v_; (v[0], v[1]) } };
    ({$v_:expr; 2}) => { { let v = $v_; {v[0], v[1]} } };

    ([$v_:expr; 3]) => { { let v = $v_; [v[0], v[1], v[2]] } };
    (($v_:expr; 3)) => { { let v = $v_; (v[0], v[1], v[2]) } };
    ({$v_:expr; 3}) => { { let v = $v_; {v[0], v[1], v[2]} } };

    ([$v_:expr; 4]) => { { let v = $v_; [v[0], v[1], v[2], v[3]] } };
    (($v_:expr; 4)) => { { let v = $v_; (v[0], v[1], v[2], v[3]) } };
    ({$v_:expr; 4}) => { { let v = $v_; {v[0], v[1], v[2], v[3]} } };
}

为了减少冗长,可以构造递归宏

macro_rules! unpack {
    ({$vec:expr; $count:expr}) => { 
        unpack!([$vec; $count])
    };
    (($vec:expr; $count:expr)) => { 
        unpack!([$vec; $count])
    };
    ([$vec:expr; $count:expr]) => { 
        $vec[0..$count]
    };
}

fn main() {
    let vec = vec![1, 2, 3, 4, 5];
    assert_eq!([1, 2], unpack!({vec; 2}));
    assert_eq!([1, 2, 3], unpack!((vec; 3)));
    assert_eq!([1, 2, 3, 4], unpack!([vec; 4]));
}
每个宏都可以用
()
[]
{}
括号调用,因此,如果不需要额外的括号对,则宏就可以这么简单:

macro_rules! unpack {
    ($vec:expr; $count:expr) => { 
        $vec[0..$count]
    };
}

fn main() {
    let vec = vec![1, 2, 3, 4, 5];
    assert_eq!([1, 2], unpack!{vec; 2});
    assert_eq!([1, 2, 3], unpack!(vec; 3));
    assert_eq!([1, 2, 3, 4], unpack![vec; 4]);
}

来自Rust Book.

为了减少冗长,可以构造递归宏

macro_rules! unpack {
    ({$vec:expr; $count:expr}) => { 
        unpack!([$vec; $count])
    };
    (($vec:expr; $count:expr)) => { 
        unpack!([$vec; $count])
    };
    ([$vec:expr; $count:expr]) => { 
        $vec[0..$count]
    };
}

fn main() {
    let vec = vec![1, 2, 3, 4, 5];
    assert_eq!([1, 2], unpack!({vec; 2}));
    assert_eq!([1, 2, 3], unpack!((vec; 3)));
    assert_eq!([1, 2, 3, 4], unpack!([vec; 4]));
}
每个宏都可以用
()
[]
{}
括号调用,因此,如果不需要额外的括号对,则宏就可以这么简单:

macro_rules! unpack {
    ($vec:expr; $count:expr) => { 
        $vec[0..$count]
    };
}

fn main() {
    let vec = vec![1, 2, 3, 4, 5];
    assert_eq!([1, 2], unpack!{vec; 2});
    assert_eq!([1, 2, 3], unpack!(vec; 3));
    assert_eq!([1, 2, 3, 4], unpack![vec; 4]);
}

铁锈书。

你读过吗?你读过吗?变量赋值可以保留吗?这是防止函数调用被多次实例化所必需的。也不确定是否依赖于
vec[0..count]
,因为解包的原因可能是将向量解包到元组中。变量赋值可以保留吗?这是防止函数调用被多次实例化所必需的。也不确定是否依赖于
vec[0..count]
,因为解包的原因可能是将向量解包到元组中。