gpt4 book ai didi

rust - 可以定义通用闭包吗?

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

Rust 是否支持具有通用返回类型的闭包?例如,我想写这样的东西:

let get<T: FromValue> = |s: &str| -> Option<T> { ... }

但是这种语法显然是错误的。

我想做什么

我正在使用 rust-mysql-simple ,我正在写一个 from_row我的方法 User结构,从数据库行构建用户。

该库不提供(据我所知)按列名查找查询结果行值的方法。因此,要解决此问题,我的方法如下所示(编译并正常工作):

fn from_row(result: &QueryResult, row: Vec<Value>) -> User {

let mut map: HashMap<_, _> = row.into_iter().enumerate().collect();

let mut get = |s: &str| {
result.column_index(s)
.and_then(|i| map.remove(&i) )
};

User {
id: get("id").and_then(|x| from_value_opt(x).ok() )
}
}

在这里,result是一个对象,其中包含有关查询列名的信息(用于查找列名的列索引),row包含查询结果行中的有序值。 from_value_opt是图书馆提供的一种方法,它接受 Value并返回 Result<T, MyError> .该值被强制转换为字段的类型。

我试图移动 .and_then(|x| from_value_opt(x).ok() )进入get关闭只是为了清理一些代码。但是,当我这样做时,闭包返回类型被解释为第一次出现 get 的结果。打电话。

我将闭包重写为嵌套方法,如下所示:

fn get<T: FromValue>(r: &QueryResult, m: &mut HashMap<usize, Value>, s: &str)
-> Option<T> { ... }

这也工作得很好,但并没有帮助减少冗长。

最佳答案

不,据我所知你不能。我的意思是,您可以定义一个通用闭包,但您不能做的是创建一个带有通用左侧的 let 绑定(bind)。​​

A fn get<T> ,就像你提到的重写一样,经历了单态化,即在编译它时,rustc 生成了一个不同版本的 get对于每个实际的 T那是用来调用它的。当您分配 get 的结果时( let a = get(...) ),该结果具有具体的类型和大小。

A let绑定(bind)不会单态化,所以你不能有 let a<T> = ...并且有不同版本的 a由编译器为您生成。

我认为可能实现这一点的是引入更高种类的类型,这是 Rust 非常需要但尚未完全充实的新功能之一。它们将使您能够编写如下内容:

// does not work as of Rust 1
let a = for<T> |s: &str, t: T| {...}

即返回一个闭包,稍后我可以用 T 对其进行参数化(这就是您所要求的)。

关于rust - 可以定义通用闭包吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34814423/

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