gpt4 book ai didi

rust - 如何在编译时将 ToString 值转换为 &str ?

转载 作者:行者123 更新时间:2023-11-29 08:12:07 26 4
gpt4 key购买 nike

TL;DR:是否可以从 const T 中创建 const … &str,其中 T : ToString?


我喜欢在使用 clap 时提供默认值.但是,clap 需要 default_value作为 &str,而不是原始类型:

pub fn default_value(self, val: &'a str) -> Self

因此,如果不是 &str,我就不能使用之前定义的 const:

use clap::{App, Arg};

/// The application's default port.
pub const DEFAULT_LISTENER_PORT : u16 = 12345;

fn main () {
let matches = App::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.arg(Arg::with_name("port")
.short("p")
.value_name("PORT")
.default_value(DEFAULT_LISTENER_PORT) // < error here
).get_matches();

}

解决方法是使用 &str 代替:

/// The application's default port.
pub const DEFAULT_LISTENER_PORT : u16 = 12345;

// Not public, since implementation detail.
const DEFAULT_LISTENER_PORT_STR : &str = "12345";

fn main () {
let matches = App::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.arg(Arg::with_name("port")
.short("p")
.value_name("PORT")
.default_value(DEFAULT_LISTENER_PORT_STR)
).get_matches();

}

但是,这两个常量很容易不同步:

/// The application's default port.
pub const DEFAULT_LISTENER_PORT : u16 = 4579;

const DEFAULT_LISTENER_PORT_STR : &str = "12345"; // whoops

因此,我想通过一些魔术函数或宏从前者生成后者:

/// The application's default port.
pub const DEFAULT_LISTENER_PORT : u16 = 4579;

const DEFAULT_LISTENER_PORT_STR : &str = magic!(DEFAULT_LISTENER_PORT);

注意:std::string::ToString::to_string不是 const,它超出范围但会在 main 中提供解决方法,例如

let port_string = DEFAULT_LISTENER_PORT.to_string();
let matches = App::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.arg(Arg::with_name("port")
.short("p")
.value_name("PORT")
.default_value(&port_string)
).get_matches();

但这也不符合人体工程学。

是否有任何我遗漏的标准宏或函数,或者是否还没有语言定义的方式来提供该功能?

最佳答案

您可以使用stringify! 宏同时定义端口整数和字符串:

macro_rules! define_port {
($port:expr) => {
pub const DEFAULT_LISTENER_PORT : u16 = $port;
const DEFAULT_LISTENER_PORT_STR : &str = stringify!($port);
}
}

define_port!(4579);

fn main() {
println!("{}:{}", DEFAULT_LISTENER_PORT, DEFAULT_LISTENER_PORT_STR);
}

或者,如果您想要更通用的:

pub struct DefaultParam<T> {
value: T,
name: &'static str,
}

macro_rules! define {
( $name:ident : $t:ty = $val:expr ) => {
pub const $name: DefaultParam<$t> = DefaultParam {
value: $val,
name: stringify!($val),
};
}
}

define!(PORT: u32 = 1234);

fn main() {
println!("{} has the value: {}", PORT.name, PORT.value);
}

关于rust - 如何在编译时将 ToString 值转换为 &str ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53722058/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com