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

How do I phrase a function's type constraint to permit the addition of values of different types?

我打算重载一些运算符,但由于语法令人费解,我正在努力实现它。作为中间步骤,我正在尝试编写一个函数来添加两个已经支持加法的值。我的函数将采用 &A 和 B 类型的值作为参数,调用一个函数将 B 转换为 C,然后克隆 A,以便我可以执行 A + C 以获得另一个 A 和 return 它。为了简化这个问题,B 是 i64,C 是 chrono 箱子中的 Duration

让我感到困惑的部分是类型边界。我怎么说你可以添加 A + Duration 以获得另一个 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>

(注:函数稍微复杂一点,我是把一种新的duration是数年数月转成大概的天数,加上date,然后向前或向后移动几天以匹配一个月中的某一天,除非起始日是 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)。

另见