2016-08-18 106 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,並且你有一個文字字符串和常量的組合。 –

相關問題