带有“where Self"的 Swift 协议条款 [英] Swift protocol with "where Self" clause

查看:40
本文介绍了带有“where Self"的 Swift 协议条款的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

除了这个带有协议扩展的语法:

In addition to this syntax with a protocol extension:

protocol P {}
extension P where Self : UIView {}

...我偶然发现您可以在协议本身上使用相同的 where 子句:

... I discovered by accident that you can use the same where clause on the protocol itself:

protocol P where Self : UIView {}

请注意,这与限制通用协议的 where 子句相同,并且本身使 P 成为通用协议.

Notice that this is not the same as a where clause constraining a generic protocol, and does not itself make P a generic protocol.

我的实验好像显示这里只能用冒号,冒号后面的一定是类或者协议(可能是泛型的).

My experiments seem to show that only a colon can be used here, and the thing after the colon must be a class or a protocol (which may be generic).

我很好奇:这是怎么引起我的注意的?所以我去寻找它何时出现的证据.在 Swift 3.0 中,前者语法是合法的,但后者.在 Swift 3.3 中,两者都是合法的.所以后一种语法肯定是在 Swift 3.2 之类的东西中悄悄引入的.我说安静"是因为我在发行说明中找不到任何相关内容.

I became curious: how did this escape my notice? So I went hunting for evidence of when it arose. In Swift 3.0, the former syntax is legal but not the latter. In Swift 3.3, both are legal. So the latter syntax must have been quietly introduced in something like Swift 3.2. I say "quietly" because I can't find anything about it in the release notes.

第二种语法是什么?看起来,它是否只是一种确保没有其他类型可以采用该协议的便捷方式?Swift 头文件似乎没有使用它.

What is the second syntax for? Is it, as it appears, just a convenient way of making sure no other type can adopt this protocol? The Swift headers do not seem to make any use of it.

推荐答案

能够在协议声明上放置超类约束(即能够定义 protocol P where Self : C where C 是类的类型)是
SE-0156,并且在实现该功能之前,Swift 4.x 中应该拒绝该语法.尝试在 Swift 4.x 中使用此功能 可能会导致错误编译和崩溃,所以我会避免在 Swift 5 之前使用它.

The ability to put superclass constraints on protocols declarations (that is, being able to define protocol P where Self : C where C is the type of a class) was a premature consequence of
SE-0156, and the syntax should have been rejected in Swift 4.x until the feature was implemented. Attempting to use this feature in Swift 4.x can cause miscompilation and crashes, so I would avoid using it until Swift 5.

在 Swift 5 (Xcode 10.2) 中,该功能现已实施.来自发行说明:

In Swift 5 (Xcode 10.2) the feature has now been implemented. From the release notes:

协议现在可以将它们的符合类型限制为那些子类化给定的类.支持两种等效形式:

Protocols can now constrain their conforming types to those that subclass a given class. Two equivalent forms are supported:

protocol MyView: UIView { /*...*/ }
protocol MyView where Self: UIView { /*...*/ } 

Swift 4.2 接受了第二种形式,但并未完全实现有时可能会在编译时或运行时崩溃.(SR-5581)(38077232)

Swift 4.2 accepted the second form, but it wasn’t fully implemented and could sometimes crash at compile time or runtime. (SR-5581) (38077232)

此语法在 MyView 上放置了一个超类约束,它将符合类型限制为从(或正在)UIView 继承的类型.此外,MyView 的用法在语义上等同于存在的类(例如 UIView & MyView),因为您可以访问该类的成员和协议的要求价值.

This syntax places a superclass constraint on MyView which restricts conforming types to those inheriting from (or being) UIView. In addition, the usage of MyView is semantically equivalent to a class existential (e.g UIView & MyView) in that you can access both members of the class and requirements of the protocol on the value.

例如,扩展发行说明的示例:

For example, expanding upon the release notes' example:

protocol MyView : UIView {
  var foo: Int { get }
}

class C : MyView {} // error: 'P' requires that 'C' inherit from 'UIView'

class CustomView : UIView, MyView {
  var foo: Int = 0
}

// ...

let myView: MyView = CustomView(frame: .zero)

// We can access both `UIView` members on a `MyView` value
print(myView.backgroundColor as Any)

// ... and `MyView` members as usual.
print(myView.foo)

这篇关于带有“where Self"的 Swift 协议条款的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆