【发布时间】:2020-12-27 20:55:35
【问题描述】:
我希望我的函数将闭包作为参数,它将PartialOrd(或任何其他特征,这只是一个示例)作为参数,并且我希望能够以任何类型调用该闭包在我的函数中实现PartialOrd。类似这样的东西:
fn my_func(cmp: fn(impl PartialOrd, impl PartialOrd) -> bool) {
cmp(3, 5);
}
但这当然不起作用,因为impl Trait 在闭包签名中无效。 (我不明白为什么,但我猜它还没有实现。)所以我尝试了这样的事情:
fn my_func<T: PartialOrd>(cmp: fn(T, T) -> bool) {
cmp(3, 5);
}
这也无法编译,因为(我猜)T 是由调用者确定的,而我只是传递了 i32,它可能与调用者打算调用的内容不同。
那么,我该怎么做呢?我的主要目的是做这样的事情:
fn my_func(cmp: fn(impl PartialOrd, impl PartialOrd) -> bool) {
if some_condition {
cmp(type1_instance, type1_instance_2);
} else {
cmp(type2_instance, type2_instance_2);
}
}
type1 和 type2 都实现了 PartialEq。
为了让它更具体,我正在使用chrono 库并想写这样的东西:
fn compare_dates(d1: DateTime, d2: DateTime, cmp: fn(impl PartialOrd, impl PartialOrd) -> bool) -> bool {
if some_condition {
cmp(d1, d2)
} else {
cmp(d1.date(), d2.date())
}
}
compare_dates(
Utc.date(2000 10, 11).and_hour(0,0,0),
Utc.date(2000 10, 12).and_hour(0,0,0),
PartialOrd::lt)
注意:DateTime::date() 不返回 DateTime,它返回不同的 Date 类型。
【问题讨论】:
-
这听起来像是XY problem。既然知道类型是
i32,为什么还要使用泛型类型参数?你有点试图做与类型参数相反的事情。my_funcfn 不决定T将是什么,调用者决定。 -
@vallentin 类型不是
i32,我在底部描述了我真正的问题是不属于XY。该参数可能是实现给定特征的两种不同类型之一。根据条件,我想使用type1或type2实例调用闭包。 -
我注意到
type*_instance*,但在那个例子中它们是什么类型?我说的是 XY 问题,因为您并没有真正给出上下文和案例的具体示例。 -
@vallentin 我进行了编辑并使用了一个更具体的示例。让我知道这是否有效。
-
你不能那样做。因为
cmp只会在你的函数声明中是通用的。因此,当您最终调用compare_dates时,T将是一个具体类型。您可能可以用Any做一些疯狂的事情来实现这一点。但是,您可能无法简单地执行compare_dates(..., PartialOrd::lt)。最简单的可能有 2 个cmpfns。你有没有一个例子说明cmp会做的不仅仅是<?
标签: rust