看了onevcat的文章哪自,覺得看了一遍什么都沒記住线得,然后似乎又都理解了顶霞。這種感覺非常好,然后就playground中操作了一遍睦擂。原鏈接onevcat
Mirror最基本的用法我們都相對比較了解得湘。
struct Cat:Dictionaryable{
var name:String
var age:Int
}
let cat = Cat(name: "onevcat", age: 20)
let mirror = Mirror(reflecting: cat)
for child in mirror.children {
print(child.label,child.value)
}
通過這種方式我們可以通過反射打印出對象中所有的屬性信息
我們可以自定義一個(gè)協(xié)議,通過協(xié)議拓展的方式返回給我們要的Any
protocol Dictionaryable{
var value:Any{get}
}
然后給一些基礎(chǔ)的數(shù)據(jù)類型默認(rèn)實(shí)現(xiàn)
extension Int:Dictionaryable{ var value: Any{return self}}
extension Double:Dictionaryable{ var value: Any{return self}}
extension Bool:Dictionaryable{ var value: Any{return self}}
extension String:Dictionaryable{ var value: Any{return self}}
通過協(xié)議拓展的方式,讓滿足它的其他類型通過Mirror的方式構(gòu)建字典
extension Dictionaryable{
var value:Any{
//1.獲取Mirror
//2.mirror的children
//3.把mirror中的label和value拼起來
//4.考慮異常的情況
let mirror = Mirror(reflecting: self)
var dict:[String:Any] = [:]
for item in mirror.children {
guard let label = item.label else { fatalError("Invalid key in child:key\(item)") }
if let value = item.value as? Dictionaryable{
dict[label] = value.value
}else{
fatalError("Invalid value in child:value\(item)")
}
}
return dict
}
}
此時(shí)自定義一個(gè)struct遵循Dictionaryable顿仇,會(huì)發(fā)現(xiàn)可以打印出對應(yīng)的dict淘正。
struct Person:Dictionaryable{
var name:String
var cat:Cat
}
let person = Person(name: "@David", cat: cat)
print(person.value)
有對象嵌套也可以,因?yàn)閯偛诺娜〉檬莍tem.value.value夺欲。如果item.value自身是自定義類型的話跪帝,會(huì)發(fā)生具體方法的調(diào)用最后返回拼接好的dict。
當(dāng)然此時(shí)無法完成Array和Dictionary的轉(zhuǎn)換些阅。此時(shí)我們要加入Array和Dictionary的拓展
Swift4.1之后已經(jīng)支持協(xié)議拓展,對拓展對象中的泛型進(jìn)行約束斑唬。
extension Dictionary: DictionaryValue where Value: DictionaryValue
{
var value: Any { return mapValues { $0.value } }
}
extension Array:Dictionaryable where Element:Dictionaryable{
var value:Any{
return ({$0.value})
}
}
但是在之前的版本還不行市埋,我們沒有辦法對拓展類型中的泛型進(jìn)行約束黎泣。我們需要在返回的方法調(diào)用中進(jìn)行強(qiáng)制轉(zhuǎn)換。
extension Array:Dictionaryable{
var value:Any{
return map({($0 as! Dictionaryable).value})
}
}
extension Dictionary:Dictionaryable{
var value:Any{
return mapValues({$0 as! Dictionaryable}).value
}
}
完成之后我們就可以進(jìn)行Array和Dictionary的轉(zhuǎn)換了缤谎。