Skip to main content

batch_impl

Attribute Macro batch_impl 

Source
#[batch_impl]
Expand description

为 trait 批量生成 impl 块的属性宏。

§语法概览

#[batch_impl( impl-spec [, impl-spec]* [ { body }]? )]
impl-spec = [ <impl-泛型> ] [ Trait名<trait-泛型> ] 目标 [ { body } ]

§^ 运算符(右结合)

A^B^C = A^(B^C)

写法展开
&^T&T
&mut^T&mut T
*const^T*const T
*mut^T*mut T
self^TT
A^BA<B>
A^<X,Y>A<X,Y>
[A1,A2]^BA1<B>, A2<B>
A^[B1,B2]A<B1>, A<B2>
[A1,A2]^[B1,B2]笛卡尔积 A1<B1>, A1<B2>, A2<B1>, A2<B2>
Box^Box^TBox<Box<T>>
Box^[Box^T]Box<[Box<T>]>
HashMap<K>^VHashMap<K, V>(预填泛型追加)
[HashMap<K>, Vec<K>]^VHashMap<K, V>, Vec<K, V>
&^Box^T&Box<T>(引用类修饰符链式应用)
*const^Vec^T*const Vec<T>
fn^(A,B)fn(A,B)(函数类型)
#[attr]^T在 impl 块前添加属性

§元组 ^(追加/生成)

追加(右侧是类型):

写法展开
()^T(T,)
(A,B)^T(A, B, T)

生成(右侧是数字或范围):

写法展开
()^N(A, B, ...)(带 N 个泛型参数)
(T)^N(T, T, ..., T)(长度为 N)
(<tr>)^N(A:tr, B:tr, ...)(带 N 个泛型参数)
()^M..N长度 M 到 N-1 的元组
()^M..=N长度 M 到 N 的元组

笛卡尔积生成(前缀含逗号):

写法展开
(T1,T2)^N长度为 N 的所有 T1/T2 组合
(<tr>,T)^N带 bound 的泛型+固定类型组合

§fn 类型

写法展开
fn^(A,B)fn(A,B)(函数类型创建)
fn(A,B)^Tfn(A,B)->T(追加返回类型)
fn-(A,B)^N生成 N 长度组合的函数类型

§- 运算符(左结合)

-^ 语义完全相同,仅结合方向不同:A-B = A^BA-B-C = (A-B)-C

写法展开
Vec-u32Vec<u32>(同 Vec^u32
HashMap-u32-StringHashMap<u32, String>(左结合,预填泛型追加)
()-[A,B](A,), (B,)
()-[A,B]-[C,D](A,C), (A,D), (B,C), (B,D)
()-[A]-[B]-[C](A,B,C)

§优先级

^ 高于 -, 最低

§其他规则

  • [] 歧义:有逗号是并列列表,无逗号是切片类型
  • () 歧义()=空元组, (A,)=单元素元组, (A)=分组(非元组)
  • trait 泛型必须显式:trait 有泛型时必须写 Trait名<T>
  • 泛型继承:嵌套 [...] 中子项不写泛型则继承父级,写了则追加并去重
  • body 继承:列表级 {...} 被所有子项共享;子项 {...} 与共享 body 合并(拼接)
  • 目标类型透传:不解析,原样透传

§基本示例

#[batch_impl(usize, isize)]
trait Numeric {}

§类型标注 / const 泛型 / 生命周期

#[batch_impl(<T: Clone + std::fmt::Debug> Vec<T>)]
trait DebugClone {}

#[batch_impl(<const N: usize> [i32; N])]
trait FixedSize {}

#[batch_impl(<'a, T: 'a> &'a T)]
trait RefTrait {}

§trait 自身带泛型参数

#[batch_impl(<T> FromValue<T> i32 {
    fn wrap(_val: T) -> Self { 0 }
})]
trait FromValue<T> { fn wrap(val: T) -> Self; }

#[batch_impl(<T> Wrapper<Vec<T>> Vec<T> {
    fn inner(self) -> Vec<T> { self }
})]
trait Wrapper<C> { fn inner(self) -> C; }

必须显式写 Trait名<泛型>,否则生成的 impl 缺少 trait 泛型。

§并列列表

#[batch_impl([usize, isize, f32] {
    fn tag(&self) -> &'static str { "number" }
})]
trait Tagged { fn tag(&self) -> &'static str; }

// 嵌套泛型合并(<U> 追加到父级 <T>,去重)
#[batch_impl(<T> Describe<T> [Vec<T>, <U> HashMap<T, U>] {
    fn describe(&self) -> String { format!("len={}", self.len()) }
})]
trait Describe<T> { fn describe(&self) -> String; }
// → impl<T>    Describe<T> for Vec<T>
// → impl<T, U> Describe<T> for HashMap<T, U>

§关联类型简洁写法

在 trait 泛型参数中使用 Name=value 语法绑定关联类型:

#[batch_impl(<T> Iter<Item=T> Vec<T> {
    fn count(&self) -> usize { self.len() }
})]
trait Iter {
    type Item;
    fn count(&self) -> usize;
}
// → impl<T> Iter for Vec<T> { type Item = T; ... }

支持多关联类型:Pair<First=T, Second=U>

§独立/共享 body 合并

列表项可有独立 body,与共享 body 合并:

#[batch_impl(
    [usize { fn name() -> &'static str { "usize" } },
     isize { fn name() -> &'static str { "isize" } }]
    { fn zero() -> Self { 0 } }
)]
trait Zero {
    fn zero() -> Self;
    fn name() -> &'static str;
}

§^ 运算符示例

#[batch_impl([&, self]^u32)]
trait RefOrOwned {}

#[batch_impl(HashMap^<u32, i32>)]
trait MapMarker {}

§多项独立 body

#[batch_impl(
    usize  { fn id(&self) -> usize { *self }      },
    String { fn id(&self) -> usize { self.len() }  }
)]
trait Identifiable { fn id(&self) -> usize; }

§复杂类型透传

#[batch_impl((i32, String), &str, Box<dyn std::fmt::Display>, dyn Fn() + Send + Sync)]
trait ComplexMarker {}

§设计约束

  • where 子句:不在 DSL 内,复杂 bound 写在 trait 定义自身
  • for<'a> 高阶 trait bound:where 子句式范畴;类型内部走 token 透传
  • <> 多参不能在 []:Rust [< 解析歧义,拆成独立表达式