可以在特征方法声明和实现中使用#[inline]吗?

时间:2017-01-19 03:50:20

标签: rust traits

我有一些使用一些小方法的特性,这些方法通常作为实现结构所具有的其他方法的单行包装器实现。如果我想确保内联trait方法,我应该将FileSize放在特征定义中,还是放在每个结构的#[inline(always)]内?我宁愿简单地把它放在特质定义中,但据我所知,它并不起作用。

1 个答案:

答案 0 :(得分:2)

inline的含义是什么?

当编译器内联一个调用时,它会在调用站点复制该函数的主体。从本质上讲,就好像代码已经在每个内联的调用站点进行了复制/粘贴。

#[inline(always)]的含义是什么?

这指示编译器始终执行内联。

通常,编译器在以下时间执行内联:

  • 函数的主体已知
  • 一组启发式估计这是一个很好的权衡(尽管可能不是),这显然取决于功能体的大小

为什么我不能在特质方法上指定#[inline(always)]

因为没有身体。

这可能听起来很陈腐,我知道,但这仍然是正确的。

在Rust中,特征可以以两种方式使用:

  • 作为边界,用于通用参数
  • 作为运行时接口,又称特征对象

当用作特征对象时,实际上没有正文:要调用的函数在运行时确定!

现在,有一些特定的优化(devirtualizations),编译器试图在其中划分或跟踪变量的实际动态类型,以避免动态调度。我甚至在GCC中看到了部分虚拟化,其中编译器计算每种类型的可能性,并为足够可能的(if)创建if A { A::call(x); } else if B { B::call(x); } else { x.call(); }阶梯。但是,当然不能保证这些成功。

那么,#[inline(always)]在虚拟呼叫中的语义是什么?编译器是否应该静默忽略该属性(呃!)?

在我看来,您正在寻找的是一个新属性(require(inline(always))?)来强制执行特征方法的特定约束。

据我所知,这还不存在。