在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
}