提问者:小点点

“__consuming”在Swift中做什么?


Sequence. swift中有一些以__consuming开头的函数(很可能还有其他地方,但我没有真正环顾四周)。我知道它是某种类型的声明修饰符,但我不确定它是做什么的。


共2个答案

匿名用户

据我所知,__consuming实际上还没有做任何事情。它是在预期实现仅移动类型的情况下添加的,此时它将用于表示一个使用它被调用的值的方法(即该值将从调用者移动到被调用者)。

为了说明,考虑这个伪代码:

// Foo is a move-only type, it cannot be copied.
moveonly struct Foo {
  consuming func bar() { // Method is marked consuming, therefore `self` is moved into it.
    print(self) // We now 'own' `self`, and it will be deinitialised at the end of the call.
  }
}

let f = Foo()
f.bar() // `bar` is a `consuming` method, so `f` is moved from the caller to the callee.
print(f) // Invalid, because we no longer own `f`.

该属性目前以两个下划线为前缀,以指示在实际实现仅移动类型之前用户不应使用它,此时它可能会被重命名为消费

正如您所发现的,一些标准库协议要求已被标记为__consuming,以表明它们可以通过仅移动类型的消费方法和非消费方法来满足。这与可变协议要求表明它可以通过值类型上的可变方法或其他非可变方法来满足大致相同(但据我所知,还没有实际的编译器逻辑支持对__consuming的检查)。

例如,Sequence上的filter(_:)要求已被标记为消费,因为采用仅移动元素的序列需要能够将适用的元素移动到结果数组中,从而使序列无效。

在实现仅移动类型之前添加该属性的原因是为Swift 5ABI稳定性冻结做准备。正如Martin所说,这在论坛上进行了更详细的讨论:

  • 为仅移动类型准备迭代ABI

匿名用户

它是Attr. def中宏定义的属性:

CONTEXTUAL_SIMPLE_DECL_ATTR(__consuming, Consuming,
  OnFunc | OnAccessor |
  DeclModifier |
  UserInaccessible |
NotSerialized, 40)