string concat error:期望文字

时间:2015-05-27 10:54:17

标签: rust

所以我有这个:

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 = $1), $2)";
    conn.execute(query, &[&user.email, concat!(&user.firstname.as_slice(), " ", &user.lastname.as_slice())]).unwrap();

}

2 个答案:

答案 0 :(得分:11)

这里有误解。

concat!是一个宏,它是一个“代码生成”机制;因此,在编译的第一阶段,在类型解析/所有权检查/等等之前,它会被扩展。

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

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

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

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

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

答案 1 :(得分:3)

Rust concat!期望文字符号文字(例如true32 'c'"string"),因为它可以在编译的最早版本中使用阶段。在此期间,类型的运行时值尚未解决。

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

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