“This is the 18th day of my participation in the Gwen Challenge in November. See details: The Last Gwen Challenge in 2021.”

A feature of Swift is the Express By-Literal protocol cluster (Literal). This is a set of protocols that allow you to instantiate objects by providing some Swift objects. For example, we can instantiate an object that provides a Boolean value or a string. Literal is a symbol for a fixed value in source code. Integers, strings, bools, floating-point numbers, arrays, and dictionaries are Literal, just as instance Array and Array literals (* Array Literal *) are two different things and should not be confused. The same is true for dictionaries.

Swift contains a series of Express ByLiteral protocols for initializing custom types with matching literals.

literal

Literals are constant values that literals represent.

species The sample
string "joke".hello world
Floating point number 100.3
integer 10.3
Boolean value true.false
An array of [1, 2, 3]
The dictionary ["name": "joke"]
empty nil

ExpressibleByNilLiteral

ExpressibleByNilLiteral is nil when an object is initialized, you don’t want the whole object to be zero, you might have a custom requirement where you need to consider the property nil to display different content. However, Apple discouragesfollowing express ByNilliteral custom types. Currently only the Optional type matches this, which is used to indicate that there is no value.

struct XWNilTest { var name: String? var sex: String? } extension XWNilTest: ExpressibleByNilLiteral{ init(nilLiteral: () {self.name = "Joke" self.sex = "male"}} let myStruct: XWNilTest = nil print(mystruct.name)//XWNilTest(name: Optional("Joke"), Sex: Optional(" male "))Copy the code

ExpressibleByStringLiteral

ExpressibleByStringLiteral can use the string to instantiate our object. String and StaticString types in accordance with ExpressibleByStringLiteral agreement, this agreement, please ensure that at least the following init (stringLiteral:) methods:

extension URL : ExpressibleByStringLiteral {
    public init(stringLiteral value: StringLiteralType) {
        guard let url = URL(string: "\(value)") else {
            preconditionFailure("This url: \(value) is not invalid")
        }
        self = url
    }
}

let url : URL = "https:www.xxx.com"
print(url)//https:www.xxx.com
Copy the code

ExpressibleByIntegerLiteral

ExpressibleByIntegerLiteral use Numbers to instantiate our object is very easy. When using this protocol, be sure to implement at least the following init(integerLiteral:) methods:

extension Date: ExpressibleByIntegerLiteral {
    public init(integerLiteral value: Int) {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyyMMdd"
        self = formatter.date(from: String(value)) ?? Date()
    }
}

let date : Date = 19941221
print(date)//**1994-12-20 16:00:00 +0000**
Copy the code

ExpressibleByFloatLiteral

Standard library Float, Float, Double conform to ExpressibleByFloatLiteral agreement. You can initialize any of these types of variables or constants by assigning floating-point literals.

struct XWFloatTest: ExpressibleByFloatLiteral {
    let value: Float
    typealias FloatLiteralType = Float
    init(floatLiteral value: Float) {
        self.value = value
    }
}

let  num: XWFloatTest = 5.5
print(num)//**WFloatTest(value: 5.5)**
Copy the code

ExpressibleByBooleanLiteral

True can be initialized with a Boolean value and false should conform to the protocol type.

struct XWBoolTest: ExpressibleByBooleanLiteral {

  typealias BooleanLiteralType = Bool
  let boolValue: Bool
   init(booleanLiteral value: BooleanLiteralType) {
     self.boolValue = value
  }
}

let  isSucc: XWBoolTest = false
print(isSucc)
Copy the code

ExpressibleByArrayLiteral

ExpressibleByArrayLiteral abide by the agreement to realize backed by an Array of custom collections.

class XWArrayTest: ExpressibleByArrayLiteral { public typealias ArrayLiteralElement = Int let numbers: [ArrayLiteralElement] public required init(arrayLiteral elements: ArrayLiteralElement...) { self.numbers = elements.map { $0 * $0 } } } let array: XWArrayTest = [2, 4, 6] print(array.numbers)//**[4, 16, 36]**Copy the code

ExpressibleByDictionaryLiteral

The corresponding Array, ExpressibleByDictionaryLiteral is mainly used for custom collection and types supported by the dictionary.

struct HTTPHeaders {
    private let headers: [String: String]
}

extension HTTPHeaders: ExpressibleByDictionaryLiteral {

    init(dictionaryLiteral elements: (String, String)...) {
        var headers: [String: String] = [:]
        for pair in elements {
            headers[pair.0] = pair.1
        }
        self = HTTPHeaders(headers: headers)
    }
}

let headers: HTTPHeaders = ["Content-Type": "application/json"]
print(headers)//**HTTPHeaders(headers: ["Content-Type": "application/json"])**
Copy the code

It is important to note that DictionaryLiteral should not be confused with an instance of Dictionary. Impossible, therefore, by assigning a Dictionary for its ExpressibleByDictionaryLiteral instance to initialize the conform to the type. The following code is incorrect:

let headersDictionary = ["Content-Type": "application/json"]
let anotherHeaders: HTTPHeaders = headersDictionary
//Cannot convert value of type '[String : String]' to specified type 'HTTPHeaders'
Copy the code