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

ajp*_*ajp 5 traits rust

我有一些小方法的特征,这些方法通常作为实现结构所具有的其他方法的单行包装器来实现。如果我想确保特征方法是内联的,我应该放置#[inline(always)]在特征定义内部,还是放在impl每个结构内部?我更愿意简单地将其放入特征定义中,但据我所知,这是行不通的。

Mat*_* M. 6

这是什么inline意思?

当编译器内联调用时,它会在调用站点复制函数体。本质上,就好像代码已被复制/粘贴到其内联的每个调用站点。

这是什么#[inline(always)]意思?

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

通常,编译器在以下情况下执行内联:

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

为什么我不能指定#[inline(always)]特征方法?

因为没有身体。

我知道,这听起来可能很老套,但这仍然是事实。

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

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

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

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

#[inline(always)]那么,虚拟调用的语义是什么?编译器是否应该默默地忽略该属性(呃!)?


在我看来,您正在寻找的是一个新属性(require(inline(always))?)来对特征方法的实现实施特定约束。

据我所知,这还不存在。

  • @Shepmaster:虽然你是对的,但如果编译器忽略了`#[inline(always)]`请求,我会非常失望。`#[inline]` 是一个提示,这很好,但是 `#[inline(always)]` 是一个命令;如果不是,甚至无法测试内联是否有益! (3认同)