默认Trait方法和参数化函数之间有什么区别?

时间:2015-09-24 06:10:47

标签: rust

在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实现总是运行完全相同的代码,无论是好是坏(无论好坏)。还有别的事吗?如果涉及相关类型或扩展特征,答案是否会改变?

1 个答案:

答案 0 :(得分:4)

你实际上自己回答了这个问题,恭喜!

由于Rust只有原则上的重载/覆盖通过特征,因此基本的语义差异是特征method可以被覆盖,因此可以自定义,而自由函数则不能。

从技术上讲,Trait::func(&self)mod::func<T: Trait>(&T)都是单一的,mod::func(&Trait)不是(因此会产生虚拟调用的轻微开销)。

此外,Trait::func(&self)还有轻微的内存开销:虚拟表中还有一个条目。它可能不明显。

很好,选择通常是判断。无论您是否打开自定义大门,都是您的选择。