Rust 如何将文本字符串与常量字符串连接起来?

Rust 如何将文本字符串与常量字符串连接起来?,rust,Rust,我试图实例化一个参数解析器(clap)。 有如下代码: const DEFAULT_VALUE: &'static str = "12312312"; // ... .help("this parameter is for (default:" + DEFAULT_VALUE + ")") // ... 我查看了类似的现有问题,发现了concat!宏和静态 第一个选项不适合,并且没有关于lazy\u static的示例。 如果可能的话,它无论如何都会过于复杂,因为lazy_static

我试图实例化一个参数解析器(clap)。 有如下代码:

const DEFAULT_VALUE: &'static str = "12312312";
// ...
.help("this parameter is for (default:" + DEFAULT_VALUE + ")")
// ...
我查看了类似的现有问题,发现了concat!宏和静态

第一个选项不适合,并且没有关于lazy\u static的示例。 如果可能的话,它无论如何都会过于复杂,因为lazy_static需要在单独的位置定义一个块

我正在寻找一些简洁的语法和宏,没有太多的类型开销

如果定义一个局部变量,它可能会变得很高,因为clap的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())
}
货舱

[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`.
:2:1:2:61错误:借来的值寿命不够长
:2$crater::fmt::format(format_args!($($arg)*)))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:11:21:11:66注:在此格式的扩展中!(定义见)
src/main.rs:13:24:15:2注:引用必须对13:23处语句0后面的块后缀有效。。。
src/main.rs:13.get_matches();
^
src/main.rs:8:5:13:24注:……但借用值仅对8:4的语句有效
src/main.rs:8让参数=App::new(“App”)
^
SRC/main:RS:8:5:13:24帮助:考虑使用“让”绑定来增加其生命周期。
src/main.rs:8让参数=App::new(“App”)
^
错误:由于上一个错误而中止
错误:无法编译'demo clap'。

您只需使用引用和
格式即可宏:

.help(&format!("this parameter is for (default: {})", DEFAULT_VALUE));
use clap::{Arg, App};  
use const_format::formatcp;  
  
const DEFAULT: &'static str = "1";  

fn main() {  
  let params = App::new("app")  
               .arg(Arg::with_name("p")  
                    .help(formatcp!("parameter p (DEFAULT: {})", DEFAULT)))  
               .get_matches();  
  println!("param p = {}", params.value_of("p").unwrap())  
}
编辑:

:

这是宏的一个基本限制,因为宏正在工作 只带着各种各样的代币。他们不了解 类型,只是看起来像类型的标记。当康卡特!见描述 它只看到一个标识符,不知道它是一个字符串 常数不过,这里可以使用的是某种字符串 连接常量fn,因为它可以将常量的值 创建新的常量,尽管这需要一些暗魔法

您可以这样做:

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宏。

如果您使用的是1或更高版本,请查看(|)上的板条箱

  • :将
    整数
    2、
    bool
    &str
    常量连接到
    &static str

  • :-类似于格式化(发出一个
    &'static str
    );使用与相同的基元

因此,对于您的示例,
formatcp
将提供最灵活的解决方案,并且不需要您提到的局部变量(我假设您指的是
format!
宏中的
alloc::fmt::format
产生的堆分配字符串):

使用app-h运行

app 

USAGE:
    app [p]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

ARGS:
    <p>    parameter p (DEFAULT: 1)
app
用法:
app[p]
旗帜:
-h、 --帮助打印帮助信息
-五、 --版本打印版本信息
ARGS:
参数p(默认值:1)

板条箱中所有宏的限制:

  • 扩展到
    &'static str
    (即我提到的那些)的宏只接受具体类型的常量:
    • 类型:::FOO
      确定✅
    • 类型:::FOO
      错误❌
  • 整数参数必须是(即,使用文字时必须添加
    i*/u*
    后缀)
  • 不能用于仅接受字符串文本的某些位置,即可能需要。
    • #[doc=“ab”]
      !=<代码>.[doc=concatcp!(“a”、“b”)]

1这是需要的,它允许在不涉及“”的情况下进行循环

2更具体地说,这将是所有的
i*/u*
原语。请注意,如果您必须自己键入,请在传入文本时使用所需的后缀

“联系人”在您的标题中。。。你是说“康卡特”吗?这不管用2:1:2:61错误:借来的值寿命不够长:2$crate::fmt::format(format_args!($($arg)*)))您能发布一个新的值吗?正如我从
clap
文档中所看到的,一些
help
方法采用
&str
,而其他方法则采用
格式,因此可能需要在
格式之前删除
&
将修复您的错误。当然,但我尝试删除&并且没有重载版本。问题不在图书馆。这是一个更普遍的问题,在DSL中有一个方法参数,它接受&str,并且要传递的是文本字符串和常量的组合。我编辑了我的答案,为您提供了一种替代方法来做您想做的事情。我不知道,但这在将来是可能的。