Protocols
Define contracts, conform with structs, and add default behavior via extensions.
Code
import Foundation
protocol Drawable {
func draw() -> String
var area: Double { get }
}
// Conforming type
struct Circle: Drawable {
let radius: Double
var area: Double { Double.pi * radius * radius }
func draw() -> String { "Circle r=\(radius)" }
}
struct Square: Drawable {
let side: Double
var area: Double { side * side }
func draw() -> String { "Square s=\(side)" }
}
// Protocol as existential type
func describe(_ shapes: [any Drawable]) {
for s in shapes {
print("\(s.draw()) area=\(s.area)")
}
}
describe([Circle(radius: 2), Square(side: 3)])
// Protocol extension with default behavior
extension Drawable {
func describe() -> String { "\(draw()) area=\(area)" }
}
let c = Circle(radius: 1)
print(c.describe())
// Protocol with associated type
protocol Container {
associatedtype Item
var count: Int { get }
mutating func append(_ item: Item)
subscript(i: Int) -> Item { get }
}Explanation
Protocols declare a contract of properties and methods that conforming types must implement. Existential types like any Drawable let you store mixed conforming types in a collection. Protocol extensions provide default implementations, giving Swift a form of trait-based composition without inheritance.
More Swift Snippets
Optionals
Use optional binding, nil-coalescing, chaining, and guard for safe unwrapping.
Closures
Define closure expressions, capture state, and pass escaping callbacks.
Generics
Write type-parameterized functions and types with protocol constraints.
Structs and Classes
Compare value-type structs with reference-type classes and inheritance.
Error Handling
Throw and catch typed errors with do-catch, try?, try!, and rethrows.
Concurrency (async/await)
Run async functions, parallelize with async let, and fan out with task groups.