Swift5.1—协议合成

简介: Swift5.1—协议合成

要求一个类型同时遵循多个协议是很有用的。你可以使用协议组合来复合多个协议到一个要求里。协议组合行为就和你定义的临时局部协议一样拥有构成中所有协议的需求。协议组合不定义任何新的协议类型。


协议组合使用 SomeProtocol & AnotherProtocol 的形式。你可以列举任意数量的协议,用和符号(&)分开。除了协议列表,协议组合也能包含类类型,这允许你标明一个需要的父类。


下面的例子中,将 NamedAged 两个协议按照上述语法组合成一个协议,作为函数参数的类型:

protocol Named {
    var name: String { get }
}
protocol Aged {
    var age: Int { get }
}
struct Person: Named, Aged {
    var name: String
    var age: Int
}
func wishHappyBirthday(to celebrator: Named & Aged) {
    print("Happy birthday, \(celebrator.name), you're \(celebrator.age)!")
}
let birthdayPerson = Person(name: "Malcolm", age: 21)
wishHappyBirthday(to: birthdayPerson)
// 打印 “Happy birthday Malcolm - you're 21!”


Named 协议包含 String 类型的 name 属性。Aged 协议包含 Int 类型的 age 属性。Person 结构体采纳了这两个协议。


wishHappyBirthday(to:) 函数的参数 celebrator 的类型为 Named & Aged, 这意味着“任何同时遵循 NamedAged 的协议”。它不关心参数的具体类型,只要参数遵循这两个协议即可。


上面的例子创建了一个名为 birthdayPersonPerson 的实例,作为参数传递给了 wishHappyBirthday(to:) 函数。因为 Person 同时遵循这两个协议,所以这个参数合法,函数将打印生日问候语。


这里有一个例子:将 Location 类和前面的 Named 协议进行组合:

class Location {
    var latitude: Double
    var longitude: Double
    init(latitude: Double, longitude: Double) {
        self.latitude = latitude
        self.longitude = longitude
    }
}
class City: Location, Named {
    var name: String
    init(name: String, latitude: Double, longitude: Double) {
        self.name = name
        super.init(latitude: latitude, longitude: longitude)
    }
}
func beginConcert(in location: Location & Named) {
    print("Hello, \(location.name)!")
}
let seattle = City(name: "Seattle", latitude: 47.6, longitude: -122.3)
beginConcert(in: seattle)
// 打印 "Hello, Seattle!"


beginConcert(in:) 函数接受一个类型为 Location & Named 的参数,这意味着“任何 Location 的子类,并且遵循 Named 协议”。在这个例子中,City 就满足这样的条件。


birthdayPerson 传入 beginConcert(in:) 函数是不合法的,因为 Person 不是 Location 的子类。同理,如果你新建一个类继承于 Location,但是没有遵循 Named 协议,而用这个类的实例去调用 beginConcert(in:) 函数也是非法的。

目录
相关文章
|
8月前
|
Swift iOS开发
Swift 语言: 什么是协议(Protocol)?如何实现和使用协议?
Swift 语言: 什么是协议(Protocol)?如何实现和使用协议?
219 2
|
算法 Swift C++
34 Swift为了协议 关联类型
Swift为了协议 关联类型
79 0
|
存储 Swift iOS开发
31 Swift 继续聊聊协议扩展
Swift 继续聊聊协议扩展
123 0
|
2月前
|
存储 Swift 开发者
Swift 协议
Swift 协议
30 0
|
8月前
|
设计模式 Swift iOS开发
【Swift开发专栏】Swift中的协议与委托模式
【4月更文挑战第30天】Swift编程语言强调协议与委托模式。协议定义了类型需实现的方法和属性,如`SomeProtocol`示例。遵循协议的类、结构体或枚举需实现协议要求。协议可继承,也可作为类型使用。委托模式让对象间通信更灵活,通过协议实现,如`DataSourceDelegate`示例。实战案例展示了在`UITableView`和自定义下载器中使用委托模式。
143 0
|
6月前
|
存储 安全 Swift
Swift高级特性:泛型与协议
【7月更文挑战第10天】Swift高级特性:泛型与协议增强代码复用与类型安全。泛型允许编写通用代码,如`swap`函数和泛型`Stack`结构体,支持类型约束如`Comparable`。协议定义行为蓝图,类型遵循协议需实现其要求。通过两者结合,构建高效灵活的代码结构。
|
Swift C++ Ruby
32 Swift面向协议编程初探
32 Swift面向协议编程初探
81 0
|
存储 前端开发 Swift
Swift实用小册20: Protocol协议的使用
在本章中,你将学会Protocol协议的使用方法。
282 0
Swift实用小册20: Protocol协议的使用
|
存储 安全 Java
Swift5.0 - day5-继承、初始化、可选链、协议(上)
Swift5.0 - day5-继承、初始化、可选链、协议(上)
134 0
Swift5.0 - day5-继承、初始化、可选链、协议(上)
|
Swift C++
Swift-进阶 10:可选类型Optional & Equatable+Comparable协议
Swift-进阶 10:可选类型Optional & Equatable+Comparable协议
356 0
Swift-进阶 10:可选类型Optional & Equatable+Comparable协议