打印!错误:预期文字/格式参数必须是字符串文字 [英] println! error: expected a literal / format argument must be a string literal

查看:48
本文介绍了打印!错误:预期文字/格式参数必须是字符串文字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个极其简单的 Rust 程序:

This extremely simple Rust program:

fn main() {
    let c = "hello";
    println!(c);
}

抛出以下编译时错误:

error: expected a literal
 --> src/main.rs:3:14
  |
3 |     println!(c);
  |              ^

在以前的 Rust 版本中,错误说:

In previous versions of Rust, the error said:

error: format argument must be a string literal.
     println!(c);
              ^

将程序替换为:

fn main() {
    println!("Hello");    
}

工作正常.

我不清楚这个错误的含义,谷歌搜索并没有真正阐明它.为什么将 c 传递给 println! 宏会导致编译时错误?这似乎是非常不寻常的行为.

The meaning of this error isn't clear to me and a Google search hasn't really shed light on it. Why does passing c to the println! macro cause a compile time error? This seems like quite unusual behaviour.

推荐答案

TL;DR 如果您不关心 为什么 并且只想修复它,请参阅 兄弟答案.

TL;DR If you don't care why and just want to fix it, see the sibling answer.

原因

fn main() {
    let c = "hello";
    println!(c);
}

无法工作是因为 println! 宏在编译时查看字符串并验证参数和参数说明符在数量和类型上是否匹配(这是一个非常好东西!).此时,在宏评估期间,无法判断 c 来自文字或函数或您拥有的东西.

Cannot work is because the println! macro looks at the string at compile time and verifies that the arguments and argument specifiers match in amount and type (this is a very good thing!). At this point in time, during macro evaluation, it's not possible to tell that c came from a literal or a function or what have you.

以下是宏扩展内容的示例:

Here's an example of what the macro expands out to:

let c = "hello";
match (&c,) {
    (__arg0,) => {
        #[inline]
        #[allow(dead_code)]
        static __STATIC_FMTSTR: &'static [&'static str] = &[""];
        ::std::io::stdio::println_args(&::std::fmt::Arguments::new(
            __STATIC_FMTSTR,
            &[::std::fmt::argument(::std::fmt::Show::fmt, __arg0)]
        ))
    }
};

我不认为编译器实际上不可能解决这个问题,但这可能需要大量的工作,但收益可能很小.宏对 AST 的一部分进行操作,而 AST 仅具有类型信息.为了在这种情况下工作,AST 必须包含标识符的来源和足够的信息来确定它是否可以用作格式字符串.此外,它可能与类型推断的交互很差 - 您想在选择类型之前就知道它!

I don't think that it's actually impossible for the compiler to figure this out, but it would probably take a lot of work with potentially little gain. Macros operate on portions of the AST and the AST only has type information. To work in this case, the AST would have to include the source of the identifier and enough information to determine it's acceptable to be used as a format string. In addition, it might interact poorly with type inference - you'd want to know the type before it's been picked yet!

错误消息要求输入字符串文字".文字"这个词是什么意思?意思是?询问这意味着什么,它链接到维基百科条目:

The error message asks for a "string literal". What does the word "literal" mean? asks about what that means, which links to the Wikipedia entry:

文字是表示源代码中固定值的符号

a literal is a notation for representing a fixed value in source code

foo" 是字符串文字,8 是数字文字.let s = "foo" 是将字符串文字的值分配给标识符(变量)的语句.println!(s) 是为宏提供标识符的语句.

"foo" is a string literal, 8 is a numeric literal. let s = "foo" is a statement that assigns the value of a string literal to an identifier (variable). println!(s) is a statement that provides an identifier to the macro.

这篇关于打印!错误:预期文字/格式参数必须是字符串文字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆