Инициализируем собственный тип с помощью литерала массива

swift4

#1

Имеем структуру Point

struct Point {
    let x: Int
    let y: Int
}

И хотим её инициализировать таким образом

let point: Point = [13, 31]

Для этого Point должен соответствовать протоколу ExpressibleByArrayLiteral и реализовывать метод init(arrayLiteral:)

extension Point: ExpressibleByArrayLiteral {
    init(arrayLiteral elements: Int...) {
        guard elements.count == 2 else { fatalError() }
        self.init(x: elements.first!, y: elements.last!)
    }
}

После чего, комфортно используем :slight_smile:

func print(point: Point) {
    print(point)
}
print(point: [43, 34])

Swift Literal Convertibles
Initialization with Literals


#2

А можно ли наоборот из struct сделать массив значений?


#3

Вы имеете в виду получить массив свойств структуры?


#4

Да, в этом смысле…


#5

К сожалениею это не возможно со структурами или классами. (может я чего и не знаю)
Это возможно только с перечислениями (enum).


#6
struct User {
    let name: String
    let age: Int
    
    var dict: [String: Any] {
        return Mirror(reflecting: self).children.reduce(into: [String: Any]()) { result, item in
            result[item.label!] = item.value
        }
    }
    
    var array: [Any] {
        return Mirror(reflecting: self).children.map { $0.value }
    }
}

let user = User(name: "Vasa", age: 100)
print(user.dict) // ["name": "Vasa", "age": 100]
print(user.array) // ["Vasa", 100]

#7

Если это все же возможно, почему это не сделали в виде протокола?


#8

Видимо незачем :slight_smile:


#9

Ну для енумов же сделали, хотя до версии 4.2 так же нужно было самим реализовывать.


#10

Значит в swfit 5 сделают.