我知道该特征的方法没有主体,因此没有内联的内容。但是,有没有办法这样标记其默认实现?
trait Magnitude {
fn square_magnitude( &self ) -> f64;
#[inline]
fn magnitude( &self ) -> f64 {
self.square_magnitude().sqrt()
}
}
实现类型的特征时,我是否需要重写整个方法主体并用#[inline]
标记此impl的方法,而不是像上面那样仅标记特征的方法?
答案 0 :(得分:3)
如果我正确理解了这个问题,那么您在问两件事:
magnitude
?square_magnitude
的代码本身未声明为magnitude
,即使square_magnitude
的代码本身未声明为inline
,编译器仍能够在square_magnitude
中内联对trait Magnitude {
fn square_magnitude( &self ) -> f64;
#[inline]
fn magnitude( &self ) -> f64 {
self.square_magnitude().sqrt()
}
}
struct Vector { x: f64, y: f64 }
impl Magnitude for Vector {
#[inline]
fn square_magnitude (&self) -> f64 {
self.x*self.x + self.y*self.y
}
}
pub fn test (x: f64, y: f64) -> f64 {
let v = Vector { x: x, y: y };
v.magnitude()
}
的调用可以在特征中使用吗?关于第一个,没有理由没有。至于第二个答案是肯定的,编译器将能够内联这两个函数,因为在生成代码时,这两个函数的源都可用。可以在disassembly中看到:
-O
使用rustc v1.28.0和选项example::test:
mulsd xmm0, xmm0
mulsd xmm1, xmm1
addsd xmm1, xmm0
xorps xmm0, xmm0
sqrtsd xmm0, xmm1
ret
编译:
impl Magnitude for Vector {
fn square_magnitude (&self) -> f64 {
self.x*self.x + self.y*self.y
}
}
<example::Vector as example::Magnitude>::square_magnitude:
movsd xmm1, qword ptr [rdi]
movsd xmm0, qword ptr [rdi + 8]
mulsd xmm1, xmm1
mulsd xmm0, xmm0
addsd xmm0, xmm1
ret
example::test:
mulsd xmm0, xmm0
mulsd xmm1, xmm1
addsd xmm1, xmm0
xorps xmm0, xmm0
sqrtsd xmm0, xmm1
ret
生成:
$WORKON_HOME