一.字面量(Literal)

var age = 10
var isRed = false
var name = "Jack"

上面代码中的10,false,”Jack”就是字面量

Swift自带的绝大部分类型,都支持直接通过字面量进行初始化

Bool Int Float Double String Array Dictionary Set Optional等

二.字面量协议

Swift自带类型之所以能够通过字面量初始化,是因为它们遵守了对应的协议

Expressible: 可表达的 Literal: 字面意义的,字面值;

Bool: ExpressibleByBooleanLiteral
Int: ExpressibleByIntergerLiteral
Float. Double: ExpressibleByIntergerLiteral  . ExpressibleByFloatLiteral


var a: Bool = false // ExpressibleByBooleanLiteral
var b: Int = 10 // ExpressibleByIntergerLiteral
var s: String = "jack" // ExpressibleByStringLiteral
var d: Dictionary = ["jack": 55] // ExpressibleByArrayLiteral
var o: Optional<Int> = nil // ExpressibleByNilLiteral

字面量协议应用示例

1.需求:通过给一个true/false值,来初始化一个变量为Int的值

extension Int: ExpressibleByBooleanLiteral {
    public init(booleanLiteral value: Bool) { 
        self = value ? 1 : 0
    }
}
 
var num: Int = true
print(num) // 1

2.需求: 通过一个数组和字典来初始化一个结构体

struct Point {
    var x = 0.0, y = 0.0
}

// 这是一个很神奇的事情,给我一个数组/字典,生成了一个结构体
var p: Point = [10.5, 20.5]
print(p) // Point(x: 10.5, y: 20.5)

p = ["x": 11, "y": 23]
print(p) // Point(x: 11.0, y: 23.0)

给结构体扩展,遵守对应的字面量协议,实现协议要求的方法

extension Point: ExpressibleByArrayLiteral, ExpressibleByDictionaryLiteral {
    
    /// ...接收可变参数
    init(arrayLiteral elements: Double...) {
        guard elements.count > 0 else { return }
        self.x = elements[0]
        guard elements.count > 1 else { return }
        self.y = elements[1]
    }
    
    init(dictionaryLiteral elements: (String, Double)...) {
        for (key, val) in elements {
            if key == "x" {
                self.x = val
            } else if key == "y" {
                self.y = val
            }
        }
    }
}

有点类似于C++中的转换构造函数