本篇分为两部分:
一、Swift 中的字面量转换
二、Swift 中的下标
一、Swift 中的字面量转换
所谓字面量就是指像特定的数字,字符串或者是布尔值这样能够直接了当地指出自己的类型并未变量进行赋值的值。比如下面三个都称为字面量:
let aNumber =
let astring = "Hello"
let aBool = true
在 Swift 中,Array 和 Dictionary 在使用简单的描述赋值的时候,使用的也是字面量,比如:
let anArray = [,,]
let aDictionary = ["key1": "value1", "key2": "value2"]
Swift为我们提供了一组非常有意思的接口,用来将字面量转换为特定的类型。对于那些实现了字面量转换接口的类型,在提供字面量赋值的时候,就可以简单的按照接口方法中定义的规则“无缝对应”的通过赋值的方式将值转换为对应类型。这些接口包括了各个原声的字面量,在实际开发中我们经常可能用到的有:
ArrayLiteralConvertible
BooleanLiteralConvertible
DictionaryLiteralConvertible
FloatLiteralConvertible
NilLiteralConvertible
IntegerLiteralConvertible
StringLiteralConvertible
点进去看可以发现所有的字面量转换接口都定义了一个 typealias 和对应的 init 方法。
protocol BooleanLiteralConvertible {
typealias BooleanLiteralType init(booleanLiteral value: BooleanLiteralType)
}
在 Swift 标准库中, typealias BooleanLiteralType = Bool
于是我们可以重写系统的 init 方法来自定义我们自己的类型,比如自定义自己的 Bool 类型:
enum MyBool: Int {
case myTrue, myFalse
} extension MyBool: BooleanLiteralConvertible {
init(booleanLiteral value: Bool) {
self = value ? myTrue : myFalse
}
} class test: UIViewController { override func viewDidLoad() {
super.viewDidLoad() let myTrue: MyBool = true
let myFalse: MyBool = false print(myTrue.rawValue) // 输出结果:0
print(myFalse.rawValue) // 输出结果:1
}
}
该段代码在 playground 中很难调试出来,在 swift 中比较直观。
注意:字面量是一个强大的特性,同时又是一个比较隐蔽的特性,所以在目前的实际工作中可读性并不好,也就是说同事可能不知道你写的是什么。
二、Swift 中的下标
在一个数组中,我们要取出 index 为0,2,3的元素的时候,现有的体系会比较吃力,需要枚举数组,然后循环判断是否是我们想要的位置。这里更好的做法是可以实现一个接受数组作为下标输入的读取方法:
extension Array {
subscript(input: [Int]) -> ArraySlice<Element> {
get {
var result = ArraySlice<Element>()
for i in input {
assert(i < self.count, "Index out of range")
result.append(self[i])
}
return result
}
set {
for (index, i) in input.enumerate() {
assert(i < self.count, "Index out of range")
self[i] = newValue[index]
}
}
}
} // 实例化一个数组
var arr = [,,,,]
// 取出索引为0,2,3的数组中的值
arr[[,,]]
// 重新改变索引为0,2,3的数组的值
arr[[,,]] = [-,-,-]
// 改变后的数组中的值
arr
输出结果为: