2016-08-18 87 views
0

我想实例化一个参数解析器(拍手)。 有这样的代码:如何连接一个字符串与一个常量字符串?

const DEFAULT_VALUE: &'static str = "12312312"; 
// ... 
.help("this parameter is for (default:" + DEFAULT_VALUE + ")") 
// ... 

我通过现有类似的问题一看,发现CONCAT!宏和lazy_static。

第一个选项不适合,没有lazy_static的例子。 如果可能的话,它会过于复杂,因为lazy_static需要在一个单独的位置定义一个块。

我正在寻找一些简洁的语法糖与宏,没有很多类型的开销。

如果定义一个局部变量,它可能会变高,因为拍手的DSL可能很长。这是不方便的,因为它将字符串从代码中的逻辑位置撕掉。

为整个帮助字符串定义静态变量的另一种方法,但它具有与上述方法相同的缺点以及命名空间污染。


建议使用格式的解决方案!不适合。它需要定义一个局部变量。


extern crate clap; 

use clap::{Arg, App}; 

const DEFAULT: &'static str = "1"; 

fn main() { 
    let params = App::new("app") 
     .arg(Arg::with_name("p") 
      // here 100 lines of the uninterruptable expression 
      .help(&format!("parameter p (DEFAULT: {})", DEFAULT))) 
      // here also 100 lines of the uninterruptable expression 
     .get_matches(); 
    println!("param p = {}", params.value_of("p").unwrap()) 
} 

Cargo.toml

[package] 

name = "demo-clap" 
version = "1.0.0" 
[dependencies] 

clap = "2.10.0" 

编译错误

<std macros>:2:1: 2:61 error: borrowed value does not live long enough 
<std macros>:2 $ crate :: fmt :: format (format_args ! ($ ($ arg) *))) 
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
src/main.rs:11:21: 11:66 note: in this expansion of format! (defined in <std macros>) 
src/main.rs:13:24: 15:2 note: reference must be valid for the block suffix following statement 0 at 13:23... 
src/main.rs:13   .get_matches(); 
            ^
src/main.rs:8:5: 13:24 note: ...but borrowed value is only valid for the statement at 8:4 
src/main.rs:8  let params = App::new("app") 
       ^
src/main.rs:8:5: 13:24 help: consider using a `let` binding to increase its lifetime 
src/main.rs:8  let params = App::new("app") 
       ^
error: aborting due to previous error 
error: Could not compile `demo-clap`. 
+0

您的标题中的“联系人”...你的意思是“concat”吗? –

回答

5

可以简单地用一个参考值和format!宏:

.help(&format!("this parameter is for (default: {})", DEFAULT_VALUE)); 

编辑:

What you want to do is not possible in Rust

This is a fundamental limitation of macros in that they are working with nothing more than various tokens. They have no understanding of types, just tokens that look like types. When concat! sees DESCRIPTION it just sees an identifier, it has no idea that it is a string constant. What could work here though is some sort of string concatenation const fn as that could take the values of constants to create new constants, although that would require some dark magic.

你可以这样做,而不是:

macro_rules! DEFAULT { 
    () => { "1" }; 
} 

fn main() { 
    let params = App::new("app") 
     .arg(Arg::with_name("p") 
      // here 100 lines of the uninterruptable expression 
      .help(concat!("parameter p (DEFAULT: ", DEFAULT!(), ")"))) 
      // here also 100 lines of the uninterruptable expression 
     .get_matches(); 
    println!("param p = {}", params.value_of("p").unwrap()) 
} 

使用宏来代替恒定的,您可以使用concat!宏。

+0

这不起作用。 :2:1:2:61错误:借来的值不够长 :2 $ crate :: fmt :: format(format_args!($($ arg)*))) –

+0

请问您可以发表[ MCVE(http://stackoverflow.com/help/mcve)?正如我从'clap'文档中看到的,一些'help'方法需要一个'&str',而另一些则使用'Into <&str>',所以在'format!'之前删除'&'可以解决你的错误。 – antoyo

+0

当然,但我试图删除&,没有重载的版本。问题不在图书馆。这是更普遍的问题,你在DSL中有一个方法参数,它需要&str,并且你有一个文字字符串和常量的组合。 –

相关问题