如何表述函数的类型约束以允许添加不同类型的值?



我打算重载一些操作符,但由于语法令人困惑,我正在努力做到这一点。作为中间步骤,我试图编写一个函数,将两个已经支持加法的值相加。我的函数将接受&A和B类型的值作为参数,调用一个函数将B转换为C,然后克隆A,这样我就可以执行A + C来获得另一个A并返回它。为了简化这个问题,B是i64, C是chrono箱中的Duration

让我困惑的是类型边界。我怎么说你可以添加A +持续时间来获得另一个A ?A不是Copy,但我很高兴克隆它。A的示例类型是DateDatetime,它们都实现了Datelike特性。

use std::ops;
use chrono::Duration;
use chrono::{Date, Datelike, offset::TimeZone};
fn add_datelike_and_duration<A>(a: &A, days: i64) -> A 
where A: Datelike + Clone,
... something I can't figure out ... 
{
let duration = Duration::days(days);
let new_a = a.clone() + duration;
let modified_new_a: A = ... do more stuff ...
modified new_a
}

不起作用的是:

for<'a> 'a + A: ops::Add<Output = A>

(注意:函数有点复杂。我将把一种新的持续时间,即年月数转换为近似天数,将它们添加到日期中,然后向前或向后移动几天以匹配该月的日期,除非开始的日子是31日,我们结束于一个30天的月,或者结束于2月。月和年的长度各不相同,这就很棘手了。这是XPATH YearMonth持续时间支持的一部分。

说明可以将A添加到Duration中以生成另一个A:

A: ops::Add<Duration, Output = A>
//          ^^^^^^^^ add this part

Add特征(以及std::ops中的大多数特征)有一个默认为Self的类型参数,所以当你写A: Add时,它意味着A: Add<A>,A: Add<Output = A>意味着Add<A, Output = A>。要将A添加到Duration,您必须显式覆盖此默认值。

只有当你想要添加引用时,才需要添加生存期('a)

参见

  • 我如何要求一个泛型类型实现一个操作,如添加,子,多,或Div在一个泛型函数?
  • 如何写一个trait绑定添加两个引用的泛型类型?
  • 在使用泛型类型时如何使用整数字面值?

最新更新