impl Trait
将函数参数类型从 更改为泛型是否可能是一个重大更改? Rust 参考指出:
注意:对于函数参数,泛型类型参数和
impl Trait
并不完全等价。对于泛型参数(例如)<T: Trait>
,调用者可以选择T
在调用站点使用GenericArgs明确指定 的泛型参数,例如foo::<usize>(1)
。如果impl Trait
是任何函数参数的类型,则调用者在调用该函数时永远不能提供任何泛型参数。这包括返回类型的泛型参数或任何 const 泛型。因此,将函数签名从其中一个更改为另一个可能会对函数调用者造成重大改变。
但是,如果至少有一个impl Trait
参数,则调用者不能命名任何泛型参数,这是否意味着更改impl Trait
为<T: Trait>
只能使调用者能够命名泛型参数?由于泛型已经推断出来,我们也不能破坏类型推断。
编辑:我假设每个都impl Trait
更改为不同的、唯一的泛型类型(不与其他impl Trait
s 或以前的泛型重叠)。违反这一点显然会造成破坏,感谢@啊鹿Dizzyi 指出这一点。
我在这里列出了(我认为是详尽的)impl Trait
更改为通用的案例列表。如果其中任何一个案例可能导致下游中断,请说明原因。如果我遗漏了某些案例,请解释它是否导致中断。
- 仅更改
impl Trait
// before
pub fn foo(_: impl Trait) {}
// after
pub fn foo<T: Trait>(_: T) {}
- 很多
impl Trait
,但只改变其中的一些
// before
pub fn foo(_: impl Trait1, _: impl Trait2, _: impl Trait3) {}
// after
pub fn foo<T1: Trait1, T2: Trait2>(_: T1, _: T2, _: impl Trait3) {}
- 很多
impl Trait
,全部改变
// before
pub fn foo(_: impl Trait1, _: impl Trait2, _: impl Trait3) {}
// after
pub fn foo<T1: Trait1, T2: Trait2, T3: Trait3>(_: T1, _: T2, _: T3) {}
- 一些通用类型,改变一些
impl Trait
,但保留至少一个
// before
pub fn foo<T1: Trait1>(_: T1, _: impl Trait2, _: impl Trait3) {}
// after
pub fn foo<T1: Trait1, T2: Trait2>(_: T1, _: T2, _: impl Trait3) {}
- 一些通用类型,改变所有
impl Trait
的
// before
pub fn foo<T1: Trait1>(_: T1, _: impl Trait2, _: impl Trait3) {}
// after
pub fn foo<T1: Trait1, T2: Trait2, T3: Trait3>(_: T1, _: T2, _: T3) {}