简体   繁体   English

rust 中函数接受闭包作为参数或返回闭包的惯用方式是什么?

[英]What is the idiomatic way in rust for a function accepts a closure as argument or return a closure?

What is the idiomatic way in rust for a function accepts a closure as argument or return a closure? rust 中函数接受闭包作为参数或返回闭包的惯用方式是什么?

I see it can be done in at least the below 3 ways:我认为至少可以通过以下 3 种方式完成:

// 1
pub fn run_with_envs_guard1(envs: &HashMap<&str, &str>, f: &dyn FnOnce()) {}

// 2
pub fn run_with_envs_guard2(envs: &HashMap<&str, &str>, f: Box<dyn FnOnce()>) {}

// 3
pub fn run_with_envs_guard3<F: FnOnce()>(envs: &HashMap<&str, &str>, f: F) {}

Are there really some differences among these 3 ways?这三种方式之间真的有一些区别吗? If yes, pls help to clarify, and which way is more idiomatic i should choose?如果是,请帮助澄清,我应该选择哪种方式更惯用?

I am learning rust still, sorry if all the above ways are some bad/strange things.我仍在学习 Rust,如果上述所有方法都是一些糟糕/奇怪的事情,我很抱歉。

I would prefer the third one.我更喜欢第三个。 Because the rust documentation suggest to Use FnOnce as a bound when you want to accept a parameter of function-like type and only need to call it once .因为rust 文档建议当您想要接受类函数类型的参数并且只需要调用一次时使用FnOnce作为边界

pub fn run_with_envs_guard3<F: FnOnce()>(envs: &HashMap<&str, &str>, f: F) {}

This means that the F to be bound by FnOnce (ie, F must implement FnOnce )这意味着FFnOnce绑定(即F必须实现FnOnce

Abdul answers the first half of your question (and I agree completely with what he said), so I'll take a stab at the second half. Abdul 回答了你问题的前半部分(我完全同意他所说的),所以我会在后半部分进行尝试。

If you want to return a closure from a function, you can't return a type parameter, because that implies that you're returning an instance of any FnOnce , at the caller's choice.如果您想从函数返回闭包,则不能返回类型参数,因为这意味着您将根据调用者的选择返回任何FnOnce的实例。 You can't return a &FnOnce , because you (usually) need to pass ownership to the caller.您不能返回&FnOnce ,因为您(通常)需要将所有权传递给调用者。 You could make it work with Box<FnOnce> , but that tends to just be clunky to work with.你可以让它与Box<FnOnce> ,但这往往会很笨拙。 When returning closures from functions, I'm partial to the impl trait syntax .从函数返回闭包时,我偏爱impl trait syntax

pub fn test() -> impl FnOnce() {
  || { println!("It worked!") }
}

In argument position, writing impl FnOnce() as the type of something is equivalent to defining a type argument, as Abdul did in his answer.在参数位置,将impl FnOnce()编写为某物的类型等同于定义类型参数,正如 Abdul 在他的回答中所做的那样。 However, in return position, it's an entirely new feature that returns an opaque value.然而,在返回位置,它是一个全新的特性,它返回一个不透明的值。 It says "I'm returning an FnOnce , and I'm not telling you which one it is".它说“我要返回一个FnOnce ,我不会告诉你它是哪个”。 It's the same concept as a trait object, but without the overhead of throwing it in a box.它与 trait 对象的概念相同,但没有将它扔进盒子的开销。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM