重庆时时彩组六单式 重庆时时彩犯法正规吗 重庆时时彩三码一胆 重庆时时彩平台手机版 山西福彩新时时彩 重庆时时彩走势dbshishicai88 重庆时时彩开奖视频怎么打不开了 如何破解重庆时时彩 360新时时彩删除 老时时彩20110601 重庆时时彩跨度介绍 重庆时时彩平台稳赚吗 360老时时彩怎么下注 新时时彩后2大小 重庆时时彩二星跨度走势图

轉載自泊學(boxueio.com)

在日常的開發中,我們經常需要遍歷一個enum類型的所有case。如果你Google一下解決辦法,就會發現大多都是依賴enum數據二進制結構的“黑科技”。但是,在Swift 4.2之后的版本里,故事就不這樣了,SE-0194為Swift引入了原生的case遍歷支持,也就是說,編譯器可以自動為我們生成一個包含所有case的集合了。

而唯一的條件,就是enum自身遵從protocol CaseIterable:

enum Shape: CaseIterable { case rectangle case circle case triangle
} Shape.allCases // [rectangle, circle, triangle] 

然后,我們再來看下CaseIterable的定義:

public protocol CaseIterable { associatedtype AllCases: Collection where AllCases.Element == Self static var allCases: AllCases { get }
}

可以看到,只是給遵從它的類型添加了一個靜態屬性:allCases,它是一個Collection,這個集合中的每一個元素和遵從CaseIterable的類型相同。在我們的例子中,當然就是Shape。

CaseIterable的限制

當然,CaseIterable的使用也是有限制的,例如:編譯器不會為帶有associated value的enum合成allCases屬性。原因很簡單,因為理論上說,帶有associated value的enum是擁有無窮多個case的,遍歷所有的case當然就無從談起了。例如,我們把Shape定義成這樣,編譯器就無法合成allCases了:

enum Shape: CaseIterable { case rectangle case circle(Double) case triangle
}

自定義CaseIterable

當然無法自動合成allCases并不等于我們無法自己實現某種合成的過程,例如,對于上面這種情況,我們可以這樣:

extension Shape: CaseIterable { public typealias AllCases = [Shape] public static var allCases: AllCases { return [Shape.rectangle, Shape.circle(1.0), Shape.triangle]
    }
}

在這個實現里,我們硬編碼了.circle的associated value。它沒什么實際的應用價值,只是為了展示自定義CaseIterable的方法。基于這種思路,有一種自定義CaseIterable的方法是有用的。

我們知道,optional類型也是通過enum實現的,但是由于它的case是帶有associated value的,因此,Swift編譯器無法自動為optional類型合成allCases。也就是說:Shape?.allCases是無法通過編譯的的。不過沒關系,我們也可以自己來:

extension Optional: CaseIterable where Wrapped: CaseIterable { public typealias AllCases = [Wrapped?] public static var allCases: AllCases { return Wrapped.allCases.map { $0 } + [nil]
    }
}

在這個實現里,我們先用了Swift 4.1中的conditional conform,約束了只有optional包裝的類型自身遵從CaseIterable這種情況。在這種情況下,我們先用Wrapped.allCases.map { $0 }得到非nil值的數組,然后,再把nil硬編碼到數組結尾中就好了。

有了這個擴展之后,Shape?.allCases就可以通過編譯了,它的結果應該是:[.rectange, .circle, .triangle, nil](這里,假設.circle是沒有associated value的)。

返回
頂部
重庆时时彩平台投注图
重庆时时彩组六单式 重庆时时彩犯法正规吗 重庆时时彩三码一胆 重庆时时彩平台手机版 山西福彩新时时彩 重庆时时彩走势dbshishicai88 重庆时时彩开奖视频怎么打不开了 如何破解重庆时时彩 360新时时彩删除 老时时彩20110601 重庆时时彩跨度介绍 重庆时时彩平台稳赚吗 360老时时彩怎么下注 新时时彩后2大小 重庆时时彩二星跨度走势图
毒品真的那么赚钱吗 千炮捕鱼经典破解版购物免费 开网店性最赚钱 荒野大镖客2合法赚钱 QQ转发点击赚钱 奔驰宝马游戏app下载 广东快乐十分人工计划 河北快3开奖直播现场 吉林快三口诀大小口诀