【发布时间】:2021-03-17 09:04:10
【问题描述】:
baz 中的 trait 绑定在 flag=true 时是不必要的强,在这种情况下我们只需要 Foo。
我希望baz 可以接受where T: Foo 并且仅在flag=false 时强制执行Bar 绑定。
trait Foo {}
trait Bar: Foo {}
fn foo<T>(t: T) where T: Foo {}
fn bar<T>(t: T) where T: Bar {}
fn baz<T>(t: T, flag: bool)
where T: Bar
{
if flag {
foo(t);
} else {
bar(t);
}
}
将绑定更改为where T: Foo 当然不会编译:
bar(t).........^ trait
Bar没有为T实现
引入一个可以被!Bar 类型调用的新函数quux 可能是我必须接受的解决方案。
但是Bar 和!Bar 类型有什么办法都可以访问单个函数baz?
如果flag=false 和T: !Bar 是可接受的,则涉及运行时恐慌的解决方案。
【问题讨论】:
-
我看不出把它分成两个函数是如何“破坏 API”的。如果
baz()函数已经存在并带有Foo特征绑定,则添加带有Bar绑定的新函数不应破坏任何现有代码。 -
事实上它以
Bartrait bound 的形式存在,我刚刚粘贴了无法编译的trait bound 的Foo形式。 -
所以您想松开绑定在
baz上的特征,从当前的Bar到问题中显示的Foo(这不会编译)? “打破” API 是指将其分解为两个函数,而不是像进行向后不兼容的更改那样打破? -
是的。我会编辑这个问题,希望这会变得更清楚。
-
感谢您的编辑。我认为你所要求的在当前的 Rust 中是不可能的,但通过专业化是可能的。专业化可能允许您定义一个新特征并实现它来为
T: Foo做一件事,为T: Bar做另一件事(由于重叠,目前不允许这样做)。然后baz会从该特征中调用该方法,这将解决正确的问题。