string concat error: expected a literal

string concat error: expected a literal

所以我有这个:

struct User {
    reference: String,
    email: String,
    firstname: String,
    lastname: String
}

fn main() {

    let user = User {
        reference: "ref".to_string(),
        email: "em@ail.com".to_string(),
        firstname: "John".to_string(),
        lastname: "Doe".to_string()
    };

    concat!(&user.firstname.as_string(), " ", &user.lastname.as_string());

}

返回错误:

error: expected a literal
concat!(&user.firstname.as_string(), " ", &user.lastname.as_string());
        ^~~~~~~~~~~~~~~~~~~~~~~~~~

但我认为 .as_string() 已经使它成为文字,不是吗?我还发现到处都是 as_slice()as_str() 引用,这令人困惑。是哪一个?

更新 好吧,我希望我不必把整个东西都粘贴在这里,但我想我无论如何都必须这样做:

extern crate postgres;

use postgres::{Connection, SslMode};

struct User {
    reference: String,
    email: String,
    firstname: String,
    lastname: String
}

fn main() {

    let conn = Connection::connect("postgres://postgres:postgres@localhost/mydb", &SslMode::None).unwrap();

    let user = User {
        reference: "ref".to_string(),
        email: "em@ail.com".to_string(),
        firstname: "John".to_string(),
        lastname: "Doe".to_string()
    };
    let query = "INSERT INTO foo (user_id, name) VALUES ((SELECT id FROM user WHERE email = ), )";
    conn.execute(query, &[&user.email, concat!(&user.firstname.as_slice(), " ", &user.lastname.as_slice())]).unwrap();

}

Rust concat! 期望符号文字中的文字(如 true32 'c'"string"),因为它在最早的部分工作编译阶段。在此期间,类型的运行时值尚未解析。

根据您的 postgress 示例,最好的做法似乎是简单地创建一个 returns 全名或任何您需要的函数:

struct User {
    ... //same
}

impl User {

   fn get_fullname(&self) -> String
   {
       let mut fullname = String::new();
       fullname.push_str(&self.firstname);
       fullname.push_str(" ");
       fullname.push_str(&self.lastname);
       fullname
   }
}

fn main() {

    let user = User {
        reference: "ref".to_string(),
        email: "em@ail.com".to_string(),
        firstname: "John".to_string(),
        lastname: "Doe".to_string()
    };
    let x = &[&user.email, &user.get_fullname()];
    conn.execute(query, &[x]);

我建议这样做,因为获取全名似乎是您希望在结构中经常使用的东西。但是,如果没有,您可以按照 Matthiueu M. 的建议设置值的格式,并假设这是一次性的,只需将它们连接起来即可。

(Playground)

这里有误会。

concat!是一个宏,也就是一个"code-generation"机制;结果,它在编译的第一阶段展开,在键入 resolution/ownership checks/etc...

之前

文字是在代码中原样写入的值:true1"hello";表达式 的结果不能 是文字(根据定义)。生成的类型可能看起来相似(甚至相同),但类型在这里无关紧要。


那么,你真正想要的是什么?我猜你只是想连接字符串。对于 String,您可以只使用 +:

let fullname = user.firstname + " " + user.lastname;
conn.execute(query, &[&user.email, &fullname]).unwrap();

或者,如果您需要一些更复杂的格式,您可以使用 format! 宏(它不需要文字),这里是:

let fullname = format!("{} {}", user.firstname, user.lastname);