为什么不允许在格式中重复使用相同的值!宏

tsh*_*ang 8 rust

鉴于:

fn main() {
    println!("{0} {0:?}", 10);
}
Run Code Online (Sandbox Code Playgroud)

我明白了:

main.rs:2:27: 2:29 error: argument redeclared with type `?` when it was previously ``
main.rs:2     println!("{0} {1:?}", 10);
                                    ^~
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)

我被迫做:

println!("{0} {1:?}", 10, 10);
// OR
println!("{} {:?}", 10, 10);
Run Code Online (Sandbox Code Playgroud)

为什么这样的限制强加给我?

Lam*_*iry 6

这是由于格式系统的限制。

在内部,println!(更准确地说,format_args!)将其参数打包到一个数组中,将每个参数与其格式类型配对。例如,以下表达式:

println!("{2} {0:?} {1:x}", 1, 2, 3);
Run Code Online (Sandbox Code Playgroud)

产生这个参数数组:

match (&1, &2, &3) {
    (__arg0, __arg1, __arg2) => [
        ::std::fmt::argument(::std::fmt::Debug::fmt, __arg0),
        ::std::fmt::argument(::std::fmt::LowerHex::fmt, __arg1),
        ::std::fmt::argument(::std::fmt::Display::fmt, __arg2)
        ]
}
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,您可以使用 看到完整的扩展rustc -Z unstable-options --pretty=expanded main.rs

这解释了为什么您的示例不起作用:如果您希望第一个参数 ( __arg0)既是 Debugand Display,那么您会将第二种类型放在哪里?

没有办法在不使系统复杂化的情况下解除这个限制,所以很遗憾我们只能解决它。


Ste*_*nik 0

它并不禁止您重复使用相同的值:

fn main() {
    println!("{0} {0}", 10);
}
Run Code Online (Sandbox Code Playgroud)

工作得很好。

问题是错误消息所说的内容:

argument redeclared with type `?` when it was previously ``
Run Code Online (Sandbox Code Playgroud)

您尝试将相同的参数用作两种不同的类型,这并不酷。我不是 100% 确定为什么不是,但事实并非如此。