在Rust中,在编写具有特征的模块时,我倾向于设计问题。我不总是确定我是否想要:
pub trait Foo {
fn foo(&self) -> bool;
fn bar(&self) {
if self.foo() {
// Do something!
} else {
// Do something else!
}
}
}
或者
pub trait Foo {
fn foo(&self) -> bool;
}
pub fn bar<T>(fooer: &T) where T: Foo {
if fooer.foo() {
// Do something!
} else {
// Do something else!
}
}
(当然,真实的例子可能有更复杂的特征或功能签名)
虽然设计问题超出了Stack Overflow的范围,但我并不完全确定我甚至理解两者之间有意义的,客观的差异,而且我觉得浏览标准库并没有太多亮点。 似乎就像Rust的标准库在大多数情况下更喜欢使用variable.method()
而不是mod::function(&variable)
。然而,这仍然没有真正回答这个问题,因为这只是一个风格指南论证,而不是基于对差异的客观认识。
除了明显的语法差异外,默认特征方法和模块级参数化函数之间的主要功能差异是什么?我遇到的一个重要问题是:默认特征方法是单形的还是使用静态调度,还是将self
视为特征对象?
我唯一看到的不同之处在于,impl
特征可能会选择覆盖默认方法实现,希望/可能提供一个实现同样合同的实现,而我我保证mod::function
实现总是运行完全相同的代码,无论是好是坏(无论好坏)。还有别的事吗?如果涉及相关类型或扩展特征,答案是否会改变?
答案 0 :(得分:4)
你实际上自己回答了这个问题,恭喜!
由于Rust只有原则上的重载/覆盖通过特征,因此基本的语义差异是特征method
可以被覆盖,因此可以自定义,而自由函数则不能。
从技术上讲,Trait::func(&self)
和mod::func<T: Trait>(&T)
都是单一的,mod::func(&Trait)
不是(因此会产生虚拟调用的轻微开销)。
此外,Trait::func(&self)
还有轻微的内存开销:虚拟表中还有一个条目。它可能不明显。
很好,选择通常是判断。无论您是否打开自定义大门,都是您的选择。