扩展 #
一、扩展概述 #
扩展可以为现有的类、结构体、枚举或协议添加新功能。
1.1 扩展能力 #
- 添加计算属性
- 添加方法
- 添加初始化器
- 添加下标
- 遵循协议
- 定义嵌套类型
二、计算属性 #
2.1 添加属性 #
swift
extension Double {
var km: Double { return self * 1000 }
var m: Double { return self }
var cm: Double { return self / 100 }
var mm: Double { return self / 1000 }
}
let distance = 1.5.km
print("\(distance)米")
let height = 180.cm
print("\(height)米")
2.2 扩展标准库 #
swift
extension String {
var length: Int {
return count
}
var reversed: String {
return String(self.reversed())
}
var isNotEmpty: Bool {
return !isEmpty
}
}
let text = "Hello"
print(text.length)
print(text.reversed)
print(text.isNotEmpty)
三、方法 #
3.1 实例方法 #
swift
extension Int {
func times(_ action: () -> Void) {
for _ in 0..<self {
action()
}
}
func squared() -> Int {
return self * self
}
}
5.times {
print("Hello")
}
print(5.squared())
3.2 可变方法 #
swift
extension Int {
mutating func square() {
self = self * self
}
}
var number = 5
number.square()
print(number)
3.3 类型方法 #
swift
extension String {
static func random(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyz"
return String((0..<length).map { _ in letters.randomElement()! })
}
}
print(String.random(length: 10))
四、初始化器 #
4.1 添加初始化器 #
swift
struct Size {
var width: Double
var height: Double
}
extension Size {
init(square side: Double) {
self.init(width: side, height: side)
}
}
let square = Size(square: 10)
print("宽: \(square.width), 高: \(square.height)")
4.2 扩展标准类型 #
swift
extension Double {
init?(fromString string: String) {
guard let value = Double(string) else {
return nil
}
self = value
}
}
if let value = Double(fromString: "3.14") {
print(value)
}
五、下标 #
5.1 添加下标 #
swift
extension String {
subscript(i: Int) -> String {
guard i >= 0 && i < count else { return "" }
let index = self.index(startIndex, offsetBy: i)
return String(self[index])
}
subscript(range: Range<Int>) -> String {
let start = index(startIndex, offsetBy: range.lowerBound)
let end = index(startIndex, offsetBy: range.upperBound)
return String(self[start..<end])
}
}
let text = "Hello"
print(text[0])
print(text[1..<4])
5.2 数组扩展 #
swift
extension Array {
subscript(safe index: Int) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}
let numbers = [1, 2, 3, 4, 5]
print(numbers[safe: 2] ?? 0)
print(numbers[safe: 10] ?? 0)
六、嵌套类型 #
6.1 添加嵌套类型 #
swift
extension Int {
enum Kind {
case negative, zero, positive
}
var kind: Kind {
switch self {
case 0: return .zero
case let x where x > 0: return .positive
default: return .negative
}
}
}
print(5.kind)
print((-3).kind)
print(0.kind)
七、协议遵循 #
7.1 遵循协议 #
swift
struct Person {
var name: String
var age: Int
}
extension Person: CustomStringConvertible {
var description: String {
return "\(name), \(age)岁"
}
}
let person = Person(name: "张三", age: 25)
print(person)
7.2 条件遵循 #
swift
extension Array: CustomStringConvertible where Element: CustomStringConvertible {
var description: String {
return "[" + map { $0.description }.joined(separator: ", ") + "]"
}
}
7.3 多协议遵循 #
swift
extension Person: Equatable, Comparable {
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name && lhs.age == rhs.age
}
static func < (lhs: Person, rhs: Person) -> Bool {
return lhs.age < rhs.age
}
}
八、实际应用 #
8.1 颜色扩展 #
swift
extension UIColor {
convenience init(hex: String, alpha: CGFloat = 1.0) {
var hexFormatted = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
hexFormatted = hexFormatted.replacingOccurrences(of: "#", with: "")
var rgbValue: UInt64 = 0
Scanner(string: hexFormatted).scanHexInt64(&rgbValue)
self.init(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: alpha
)
}
}
let color = UIColor(hex: "#FF8000")
8.2 日期扩展 #
swift
extension Date {
var isToday: Bool {
return Calendar.current.isDateInToday(self)
}
var isYesterday: Bool {
return Calendar.current.isDateInYesterday(self)
}
var isTomorrow: Bool {
return Calendar.current.isDateInTomorrow(self)
}
func format(_ format: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.string(from: self)
}
}
let now = Date()
print(now.isToday)
print(now.format("yyyy年MM月dd日"))
8.3 数组扩展 #
swift
extension Array {
func chunked(into size: Int) -> [[Element]] {
guard size > 0 else { return [] }
return stride(from: 0, to: count, by: size).map {
Array(self[$0..<Swift.min($0 + size, count)])
}
}
func unique<T: Hashable>(by keyPath: KeyPath<Element, T>) -> [Element] {
var seen = Set<T>()
return filter { seen.insert($0[keyPath: keyPath]).inserted }
}
}
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(numbers.chunked(into: 3))
九、总结 #
本章学习了Swift扩展:
- 计算属性:添加属性
- 方法:添加实例和类型方法
- 初始化器:添加构造函数
- 下标:添加下标访问
- 协议遵循:实现协议
最佳实践:
- 使用扩展组织代码
- 扩展标准库增加便利功能
- 使用扩展分离协议实现
- 避免过度扩展
下一章,我们将学习高级特性!
最后更新:2026-03-26