You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建Rust的<tr><td>宏?解决多列表格生成语法报错问题

问题

我有不少不同列数的数据集要插入表格,觉得Yew框架太冗余,想按KISS原则简化操作。原本用这种方式生成表格行:

// format!("<tr><td>{e1}</td><td>{e2}</td></tr>") – 不行,参数可能是表达式
format!("<tr><td>{}</td><td>{}</td></tr>", e1, e2)

我想改成支持任意列数的宏,试了这段代码:

macro_rules! tr {
    ($($td:expr),*) => {
        format!(concat!("<tr>", $("<td>{}</td>"),* "</tr>"), $($td),*)
    }
}
tr!(e1, e2)

结果报错:attempted to repeat an expression containing no syntax variables matched as repeating at this depth

于是我改成这样:

macro_rules! tr {
    ($($td:expr),*) => {
        format!(concat!("<tr>", $({ $td; "<td>{}</td>" }),* "</tr>"), $($td),*)
    }
}

又报错:expected token: ,

正确的语法应该怎么写?

解决方案

问题出在宏里concat!的重复语法不符合Rust宏规则:第一个错误是因为重复块$("<td>{}</td>"),*里没有引用宏捕获的重复变量$td,Rust宏要求重复块必须包含对应的重复捕获项;第二个错误是用了${ ... }这种无效的宏语法。

正确的写法如下,同时支持末尾可选逗号(更易用):

macro_rules! tr {
    ($($td:expr),* $(,)?) => {
        format!(
            concat!("<tr>", $( "<td>{}</td>" ),* "</tr>"),
            $($td),*
        )
    };
}

说明

  • concat!("<tr>", $( "<td>{}</td>" ),* "</tr>") 会根据传入的参数数量,自动生成对应个数的<td>{}</td>片段,拼接成完整的HTML模板字符串。
  • $(,)?) 允许宏接受末尾带逗号的参数(比如tr!(a, b,)),使用起来更灵活。

测试示例:

fn main() {
    let col1 = "姓名";
    let col2 = "年龄";
    let col3 = "城市";
    println!("{}", tr!(col1, col2)); // 输出: <tr><td>姓名</td><td>年龄</td></tr>
    println!("{}", tr!(col1, col2, col3)); // 输出: <tr><td>姓名</td><td>年龄</td><td>城市</td></tr>
}

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:45:13