作为契约的协议
定义独立于类型的行为契约。
作为契约的协议 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
什么是协议
协议定义了一个蓝图,其中包含遵循该协议的类型必须实现的方法、属性和其他要求。它是一份契约:任何采用该协议的类型都承诺提供协议声明的全部内容。
protocol Greetable {
var name: String { get }
func greet() -> String
}遵循协议
类型通过采用协议并提供每项要求来遵循协议。这里的结构体同时满足了 name 属性和 greet() 方法的要求。
protocol Greetable {
var name: String { get }
func greet() -> String
}
struct Person: Greetable {
let name: String
func greet() -> String { "Hello, I am " + name }
}
let p = Person(name: "Ada")
print(p.greet())属性要求
协议会规定属性是否必须可读取({ get }),或必须既可读取又可设置({ get set })。存储属性或计算属性都可以满足仅要求读取的属性要求。
protocol Identifiable {
var id: String { get }
}
struct User: Identifiable {
let id: String
}
print(User(id: "u-1").id)方法要求
方法要求会列出名称、参数和返回类型,但不包含方法体。遵循协议的类型负责提供具体实现。
protocol Shape {
func area() -> Double
}
struct Square: Shape {
let side: Double
func area() -> Double { side * side }
}
print(Square(side: 3).area())可变更要求
对于值类型,修改 self 的方法必须标记为 mutating。请使用 mutating 声明该要求,以便结构体能够满足它。
protocol Toggleable {
mutating func toggle()
}
struct Switch: Toggleable {
var isOn = false
mutating func toggle() { isOn.toggle() }
}
var s = Switch()
s.toggle()
print(s.isOn)将协议用作类型
协议是一等类型。您可以将它用于变量、参数和返回值,从而接受任何遵循该协议的值。
protocol Animal { func sound() -> String }
struct Dog: Animal { func sound() -> String { "Woof" } }
struct Cat: Animal { func sound() -> String { "Meow" } }
let animals: [Animal] = [Dog(), Cat()]
for a in animals { print(a.sound()) }通过协议实现多态
调用协议方法时,会将调用分派到值背后的具体类型。这让您可以通过一份契约编写适用于多种类型的代码。
protocol Describable { func describe() -> String }
struct Book: Describable { let t: String; func describe() -> String { "Book: " + t } }
struct Film: Describable { let t: String; func describe() -> String { "Film: " + t } }
func show(_ d: Describable) { print(d.describe()) }
show(Book(t: "Swift"))
show(Film(t: "Inception"))初始化器要求
协议可以要求初始化器。类必须将实现标记为 required,这样子类也必须提供该初始化器。
protocol FromInt {
init(value: Int)
}
struct Wrapper: FromInt {
let value: Int
init(value: Int) { self.value = value }
}
print(Wrapper(value: 42).value)协议继承
一个协议可以继承一个或多个其他协议,并在继承的要求之上增加额外要求。
protocol Named { var name: String { get } }
protocol Aged: Named { var age: Int { get } }
struct Member: Aged {
let name: String
let age: Int
}
let m = Member(name: "Lin", age: 30)
print(m.name, m.age)仅限类的协议
使用 AnyObject 标记协议,可以将遵循协议的类型限制为类。这对于委托等需要引用语义的场景很有用。
protocol Counter: AnyObject {
var count: Int { get set }
}
class Box: Counter {
var count = 0
}
let b = Box()
b.count = 5
print(b.count)检查是否遵循协议
使用 is 和 as?,可以在运行时测试某个值是否遵循协议。
protocol Flyer { func fly() }
struct Bird: Flyer { func fly() { print("flap") } }
struct Rock {}
let things: [Any] = [Bird(), Rock()]
for t in things {
if let f = t as? Flyer { f.fly() } else { print("grounded") }
}快速检查
测试您对协议要求的理解。
回顾
您已经学习了协议是一份契约:它声明属性、方法、可变更和初始化器要求,但不提供实现。类型通过满足每项要求来遵循协议;协议可以作为类型用于多态,可以继承其他协议,也可以使用 AnyObject 将遵循者限制为类。
常见问题解答
「作为契约的协议」课时是免费的吗?
是的 — 「作为契约的协议」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「作为契约的协议」这节课中我会学到什么?
定义独立于类型的行为契约。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「作为契约的协议」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。