gpt4 book ai didi

rust - 在 Rust 的编译时部分应用?

转载 作者:行者123 更新时间:2023-11-29 08:35:50 25 4
gpt4 key购买 nike

我有一个函数接受两个参数(比方说两个字符串):

fn foo(x: String, y: String) -> String {
x + y
}

我总是在编译时知道x,但直到运行时我才知道y

如何在不为每个 x 复制粘贴函数的情况下以最大效率编写此代码?

最佳答案

请注意,您的函数 foo 目前不必要地需要两个堆分配的字符串。这是另一个版本,它更加通用和高效(尽管我将在接下来描述 YMMV):

fn foo<T>(x: T, y: &str) -> String
where
T: Into<String>,
{
x.into() + y
}

assert_eq!(foo("mobile ", "phones"), "mobile phones");

串联几乎总是需要在某处分配内存,但这个可以采用堆分配的字符串以及任意字符串切片。如果 x 的容量足够大,它也可以避免重新分配,尽管这种情况不太可能发生,因为 x 是从已知的字符串中获得的编译时间。 String::insert_str本来可以让我们恢复类型参数的位置,但是在字符串前面插入的成本为 O(n)。就编译器可以采用的优化而言,先验知道字符串连接的第一个操作数并不是很有用。


让我们假设我们仍然想在编译时执行部分功能。这似乎是另一个用例 const generics会发光。有了这个特性,我们确实可以在 &'static str 上单态化这个函数。从 nightly-2022-06-29 开始,能够使用 &'static str 作为 const 参数仍然不稳定,但下面的代码 compiles and works as intended .此功能在 issue 95174 中进行了跟踪.

#![feature(adt_const_params)]

fn foo<const X: &'static str>(y: &str) -> String {
X.to_string() + y
}

let s = "string".to_string();
println!("{}", foo::<"I am ">(&s));

唉,应用于字符串切片的 const 泛型仍然不稳定,还没有为此做好准备。尽管不太符合人体工程学,但我们可以使用基于规则的宏来复制为每个字符串文字实例化一个函数的效果:

macro_rules! define_foo {
($fname: ident, $x: literal) => {
fn $fname (y: &str) -> String {
$x.to_string() + y
}
}
}

使用:

define_foo!(bar, "Conan ");

assert_eq!(bar("Osíris"), "Conan Osíris");

另见:

关于rust - 在 Rust 的编译时部分应用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54959438/

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