Swift Expressible literal
Swift Expressible Literal
引子
从一个面试题说起。有如下代码:
struct Book {
let name: String
}
let book: Book = "Charlotte's Web"
请问是否可以让它正常编译?
字面量
字面量指字面代表的常量值。这样解释起来有点像废话。但是通过例子就很容易理解了。
以下是 Swift 中的一些字面量:
种类 | 示例 |
---|---|
字符串 | "ich" , Bingo! |
浮点型数字 | 1001.3 , 33.0 |
整型数字 | 1001 , 33 |
布尔值 | true , false |
数组 | ["Emily", "Ben", "Eric"] |
字典 | ["name": "Ben"] |
空 | nil |
Expressible Literal 协议
Swift 中,String
, Float
, Double
, Int
和 Bool
等类型,和上面的 Book
一样,都是 struct 。那么它们是怎么实现将字面量直接创建实例的呢?以下是 Bool
类型的一个拓展:
extension Bool : ExpressibleByBooleanLiteral {
/// Creates an instance initialized to the specified Boolean literal.
///
/// Do not call this initializer directly. It is used by the compiler when
/// you use a Boolean literal. Instead, create a new `Bool` instance by
/// using one of the Boolean literals `true` or `false`.
///
/// var printedMessage = false
///
/// if !printedMessage {
/// print("You look nice today!")
/// printedMessage = true
/// }
/// // Prints "You look nice today!"
///
/// In this example, both assignments to the `printedMessage` variable call
/// this Boolean literal initializer behind the scenes.
///
/// - Parameter value: The value of the new instance.
public init(booleanLiteral value: Bool)
/// A type that represents a Boolean literal, such as `Bool`.
public typealias BooleanLiteralType = Bool
}
再看看 Float
的一个拓展:
extension Float : ExpressibleByIntegerLiteral {
/// Creates an instance initialized to the specified integer value.
///
/// Do not call this initializer directly. Instead, initialize a variable or
/// constant using an integer literal. For example:
///
/// let x = 23
///
/// In this example, the assignment to the `x` constant calls this integer
/// literal initializer behind the scenes.
///
/// - Parameter value: The value to create.
public init(integerLiteral value: Int64)
/// A type that represents an integer literal.
///
/// The standard library integer and floating-point types are all valid types
/// for `IntegerLiteralType`.
public typealias IntegerLiteralType = Int64
}
除了 ExpressibleByBooleanLiteral
和 ExpressibleByBooleanLiteral
类似的协议还有 ExpressibleByStringLiteral
, ExpressibleByNilLiteral
, ExpressibleByArrayLiteral
等等。
所以,最开始的那个题目,就有答案了。
注意上面两个大代码块里面的注释,都有一句 Do not call this initializer directly
。
----------
追求卓越
----------