第六章:函数(function)
6.5 计算属性和下标(computed property and subscript)
知识点1: 什么是计算属性
我们直接看下面这个demo
///返回我的名字
/// 复杂度: O(1)
var myName:String {
return "liaoworking"
}
没有指定setter
方法,只读
属性,myName的值不会被缓存
,每次被调用的时候都会计算一遍。上面这个就是计算属性
注:swift API指南推荐我们对所有复杂度不是O(1)的计算属性都应该在文档中写明(如demo中所示)。因为会假设调用计算属性的耗时是常数时间。
知识点2:声明一个外部只读,内部可读写的属性
private(set) var userName:String = ""
延迟存储属性(懒加载 lazy)
相信大家经历过多年的OC懒加载的洗礼。对lazy的理解深入骨髓!
这里就只说笔者觉得可以拿来一说的几点
常规写法1:
lazy var myAge:Int = { ()-> String in
return 18
}()
常规写法2:
///getMyAge() 是一个返回Int类型的方法
lazy var myAge:Int = getMyAge()
常规写法3
///currentYear 和 birthYear是两个变量
lazy var myAge:Int = currentYear - birthYear
使用不同参数重载下标
下标的常规使用
let fibs = [0, 1, 1, 2, 3, 5]
let first = fibs[0]
fibs[1..<3] //[1, 1]
因为demo的使用场景有限,就是想重写一个只有起点(从起点到最后)
的下标表示。
这里只说说核心思想
和步骤
。 具体代码可见最后附。
我们可以重载下标
来定义一个可以使用半有界区
间为参数的collection的下标方法来实现
fibs[2..<]
步骤
:
-
1.定义一个简单的
操作符运算
来创建有界区间。
这个涉及到操作符合 ..< 操作符的定义的知识点。 -
2.给 collection 添加一个extension 把这两个subscript的方法写入即可。
下标的进阶
下标其实也可以像函数一样接受多个参数
。
实现原理
:
写一个extension的subscript
的方法即可。
Demo主要是以字典的形式展示每个字母出现个个数,Demo具体使用场景太少。了解步骤及知识点即可
。
附:
///重载下标 达到获取collection半有界区的目的
struct RangeStart<l>{let start : l}
struct RangeEnd<l>{let end : l}
postfix operator ..<
postfix func ..<<l>(lhs: l) -> RangeStart<l> {
return RangeStart(start: lhs)
}
prefix operator ..+
prefix func ..+<l>(rhs: l) -> RangeEnd<l> {
return RangeEnd(end: rhs)
}
extension Collection {
subscript(r: RangeStart<Index>) -> SubSequence {
return suffix(from: r.start)
}
subscript(r: RangeEnd<Index>) -> SubSequence {
return prefix(upTo: r.end)
}
}
fibs[2..<]
fibs[..+3]
///实现多参数下标的核心方法
extension Dictionary {
subscript(key: Key, or defaultValue: Value) -> Value {
get {
return self[key] ?? defaultValue
}
set {
self[key] = newValue
}
}
}
extension Sequence where Iterator.Element: Hashable {
var frequencies: [Iterator.Element: Int] {
var result: [Iterator.Element: Int] = [:]
for x in self {
result[x, or: 0] += 1
}
return result
}
}
"hello".frequencies // ["e":1, "0":1, "l":2, "h":1]
网友评论