如何表述函数的类型约束以允许添加不同类型的值?
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 的示例类型是 Date
和 Datetime
,它们都实现了 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
)。
另见
我打算重载一些运算符,但由于语法令人费解,我正在努力实现它。作为中间步骤,我正在尝试编写一个函数来添加两个已经支持加法的值。我的函数将采用 &A 和 B 类型的值作为参数,调用一个函数将 B 转换为 C,然后克隆 A,以便我可以执行 A + C 以获得另一个 A 和 return 它。为了简化这个问题,B 是 i64
,C 是 chrono
箱子中的 Duration
。
让我感到困惑的部分是类型边界。我怎么说你可以添加 A + Duration 以获得另一个 A(并直接获得生命周期)? A 不是 Copy
,但我很高兴克隆它。 A 的示例类型是 Date
和 Datetime
,它们都实现了 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
)。