在Rust中编译时部分应用程序?

在Rust中编译时部分应用程序?,rust,compile-time,Rust,Compile Time,我有一个函数,它接受两个参数(比如两个字符串): 我总是在编译时知道x,但直到运行时我才知道y 我如何才能在不为每个x复制粘贴函数的情况下,以最大效率编写此文件 我可以在夜间使用const函数返回闭包: #![特征(常数fn)] fn foo(x:String,y:String)->String{ x+&y } const fn foo_applicated(x:String)->impl fn(String)->String{ 移动| y | foo(x.clone(),y) } fn mai

我有一个函数,它接受两个参数(比如两个字符串):

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


我如何才能在不为每个
x
复制粘贴函数的情况下,以最大效率编写此文件

我可以在夜间使用const函数返回闭包:

#![特征(常数fn)]
fn foo(x:String,y:String)->String{
x+&y
}
const fn foo_applicated(x:String)->impl fn(String)->String{
移动| y | foo(x.clone(),y)
}
fn main(){
让foo_1=foo_应用(“1.into());
println!(“{}”,foo_1(“2.into());
让foo_2=foo_应用(“2.into());
println!(“{}”,foo_2(“1.into());
}

请注意,函数
foo
当前不必要地需要两个堆分配字符串。下面是另一个版本,它更通用、更高效(尽管我将在下面介绍YMMV):

fn foo(x:T,y:&str)->String
哪里
T:Into,
{
x、 进入()+y
}
断言!(foo)("流动电话","流动电话";;
连接几乎总是需要在某个地方进行内存分配,但这个连接可以采用堆分配的字符串以及任意字符串片。 如果
x
的容量足够大,它还可以避免重新分配,尽管考虑到
x
是从编译时已知的字符串中获得的,这种情况不太可能发生。将允许我们恢复类型参数的位置,但在字符串前面插入会产生O(n)代价。就编译器可以采用的优化而言,事先知道字符串串联的第一个操作数对编译器不是很有好处


假设我们仍然希望在编译时执行部分函数。这似乎是另一个会大放异彩的用例。有了这个特性,我们确实可以在
&'static str
上单态化这个函数。从
nightly-2021-01-14
开始,该功能不稳定,但下面的代码不稳定

#![特征(const_泛型)]

fn除了将
x
y
的类型更改为
&str
并避免无用的
字符串构造之外,我不确定在编译时有多少需要优化的地方。因此,对于
x
的每个版本,您想要一个版本的函数吗?我怀疑这就是我所说的部分应用程序。您确定这是代码中的性能瓶颈吗?如果是的话,我会非常惊讶。无论如何,如果确实如此,我建议简单地将
foo()
标记为
#[inline(always)]
,并使用普通闭包。编译器可能会在没有属性的情况下内联函数,因此没有什么需要担心的,但是如果属性让您放心,那么只需继续添加它。:)我怎样才能写这篇文章来获得最大的效率?为什么你认为你写的东西不是最大的效率?我不知道,这就是为什么我要问的。
fn foo(x: String, y: String) -> String {
    x + y
}