如何在 Rust 中连接静态字符串

32

我试图将静态字符串和字符串字面量连接起来,以构建另一个静态字符串。下面是我能想到的最佳方法,但它无法正常工作:

const DESCRIPTION: &'static str = "my program";
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const VERSION_STRING: &'static str = concat!(DESCRIPTION, " v", VERSION);
有没有在Rust中实现这个功能的方法,或者我必须一遍又一遍地编写相同的文本?

看一下 lazy_static:https://github.com/rust-lang-nursery/lazy-static.rs - starblue
引用自README:“使用此宏,可以拥有需要在运行时执行代码才能初始化的静态变量。” 在我的示例中,不应该需要在运行时执行任何代码。 - CodeMonkey
4个回答

21

由于我本质上是在尝试模拟C宏,因此我尝试使用Rust宏解决了这个问题并成功了:

macro_rules! description {
    () => ( "my program" )
}
macro_rules! version {
    () => ( env!("CARGO_PKG_VERSION") )
}
macro_rules! version_string {
    () => ( concat!(description!(), " v", version!()) )
}

使用宏而不是常量可能会有些难看,但它如预期般运行。


查看使用const_format crate的concatcp!()宏的答案。 - sshine

16

编译器错误为

错误:期望字面值

字面值是您直接输入的任何内容,例如"hello"5。一旦您开始使用常量,您就不再使用字面值而是使用标识符。所以现在您能做的最好的就是

const VERSION_STRING: &'static str =
    concat!("my program v", env!("CARGO_PKG_VERSION"));

由于env!宏会扩展为一个字面值,因此您可以在concat!中使用它。


6
所以,正如我所担心的那样,我将不得不一遍又一遍地写同样的文字。 - CodeMonkey
1
你可以尝试改进concat宏以支持常量 ;) 但是要等一个月左右才能在稳定的 Rust 中实现。 - oli_obk
“concat” 似乎是编译器内置的:https://github.com/rust-lang/rust/blob/master/src/libstd/macros.rs#L311 我真的不想修补编译器 ;) - CodeMonkey
你仍然可以在问题跟踪器中提出问题。允许在 concat! 中使用简单常量不应该是太大的问题。 - oli_obk
1
这将是一个问题,因为宏定义本质上无法知道常量的值(即使是内置的常量),它们在常量被评估之前运行,并且仅对标记进行操作。 - Cerberus
那么,为从其他&'static str创建一个&'static str,是否考虑添加内置的常量求值? - bcdan

3
另一种方法是使用 const_concat! 宏。
#[macro_use]
extern crate const_concat;

const GREETING: &str = "Hello";
const PLACE: &str = "world";
const HELLO_WORLD: &str = const_concat!(GREETING, ", ", PLACE, "!");

assert_eq!(HELLO_WORLD, "Hello, world!");

2
这个 crate 在新的 Rust 版本中似乎无法正常工作。我遇到了多个错误,比如:#![feature] 可能不能在稳定版本通道上使用等。 - Notbad

1
你可以使用const_format crate来连接不同类型的命名和字面常量。
这个crate自2020年8月起就可用,所以这个答案只能在事后才能得出。
use const_format::concatcp;

const DESCRIPTION: &'static str = "my program";
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const VERSION_STRING: &'static str = concatcp!(DESCRIPTION, " v", VERSION);

这个宏甚至可以将数字常量/字面值连接成一个&'static str

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接