Sequence. swift中有一些以__consuming
开头的函数(很可能还有其他地方,但我没有真正环顾四周)。我知道它是某种类型的声明修饰符,但我不确定它是做什么的。
据我所知,__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所说,这在论坛上进行了更详细的讨论:
它是Attr. def中宏定义的属性:
CONTEXTUAL_SIMPLE_DECL_ATTR(__consuming, Consuming,
OnFunc | OnAccessor |
DeclModifier |
UserInaccessible |
NotSerialized, 40)