2016-08-18 15 views
0

引数パーザ(clap)をインスタンス化しようとしています。私は似た既存の質問を通して見て、連結を発見リテラル文字列をconst文字列に連結する方法は?

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

: コードは次のようにあります!マクロと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" 

あなたは、単に参照およびマクロformat!を使用することができ

<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

あなたのタイトルの「連絡先」は...「連動」を意味しましたか? –

答えて

5

コンパイルエラー:

あなたが代わりにこれを行うことができます

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.

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

編集:

What you want to do is not possible in Rust

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> 'を取るので、'& 'before' format! 'を削除するとエラーになります。 – antoyo

+0

確かに、&を削除しようとしましたが、オーバーロードされたバージョンはありません。問題はライブラリではありません。これはより一般的な問題で、DSLで&strを取るメソッド引数があり、渡すリテラル文字列と定数の組み合わせがあります。 –

関連する問題