今天的內(nèi)容翻譯自Simplifying Login with Swift Enums,隱隱約約的記得好像有人翻譯過這篇內(nèi)容识虚,我本來對(duì)這篇內(nèi)容不是很感興趣,但無意中發(fā)現(xiàn)了另外一篇博文指出:《Simplifying Login with Swift Enums》這么做并不好妒茬,所以我的興趣就來了担锤,我準(zhǔn)備把兩篇內(nèi)容都整理一下,今天先發(fā)這一篇乍钻。首先要推薦大家看原文肛循,我這里并沒有逐句的對(duì)照翻譯,我是按照自己的理解重新把內(nèi)容整理了一遍银择。如果有出現(xiàn)不正確的地方歡迎大家留言給我多糠。
原作者David East根據(jù)自己的經(jīng)驗(yàn)得出一個(gè)結(jié)論:一款app在登錄操作上夹孔,如果想獲得用戶的信任和好評(píng)害捕,那么需要為用戶提供選擇尝盼,提供多種登陸方式裁赠。David East認(rèn)為swift的枚舉可以有效的對(duì)登錄邏輯進(jìn)行抽象佩捞,從而令我們能夠保持view controllers的干凈簡(jiǎn)潔莲蜘。我自己確認(rèn)為這篇內(nèi)容做為enum的基本介紹是比較合適的票渠。
使用枚舉定義社交賬號(hào)登錄
enum LoginProvider {
case Facebook
case Email
case Google
case Twitter
}
很多語言的枚舉只是出于類型安全的考慮而把普通類型打個(gè)包而已,而swift中的枚舉則是一個(gè)實(shí)實(shí)在在的 first-class杜窄,枚舉中每一個(gè)case都是一個(gè)fully-fledged value羞芍,例如:Facebook 的類型就是LoginProvider。
枚舉的Raw Values
我們可以給枚舉的每一個(gè)case存儲(chǔ)一個(gè)值畏浆,我們把這種值稱作枚舉的Raw Values刻获。
enum LoginProvider: String {
case Facebook = "facebook"
case Email = "email"
case Google = "google"
case Twitter = "twitter"
}
對(duì)于Raw Values我們應(yīng)該關(guān)注幾件事情:
- Raw Values要求枚舉的定義是有明確的返回類型,我們這里是 String
- 枚舉的每個(gè)case的類型必須是一致的
- 我們可以通過rawValue來初始化一個(gè)枚舉沐兵,參數(shù)名稱就是rawValue
let provider = LoginProvider.init(rawValue: "email")
通過定義的rawValue “email”,我們可以獲得一個(gè) Email毁靶,這個(gè)確實(shí)很方便预吆。
Associated Values
rawValue實(shí)際上是給枚舉的每個(gè)case做了一個(gè)常量的預(yù)設(shè)值觅够,那我們可不可以給每個(gè)case綁定一個(gè)變量值呢喘先?這樣的話我們就可以非常方便的給以枚舉根據(jù)特定情況綁定不同的值了。幸運(yùn)的是涤姊,swift確實(shí)提供這個(gè)能力:Associated Values
enum LoginProvider {
case Facebook
case Email(String, String)
case Google
case Twitter
}
let provider = LoginProvider.Email("bob@bob.com", "pass")
關(guān)于Associated Values我們可以關(guān)注幾件事情:
- 每個(gè)case的類型可以不同思喊,各自根據(jù)各自的需要使用類型
- 枚舉的定義上面沒有返回值了
- Associated Values可以是任意類型
我們可以定義一個(gè)user類型,然后作為枚舉的Associated Values。
struct LoginUser {
let email: String
let password: String
func isValid() -> Bool {
return email != "" && password != ""
}
}
enum LoginProvider {
case Facebook
case Email(LoginUser)
case Google
case Twitter
}
有了這樣的定義之后剂公,我們就可以創(chuàng)建一個(gè)Email枚舉了.
let provider = LoginProvider.Email(user)
在Associated Values特性的幫助下,枚舉可以“滲透到”各種問題的解決方案中去拖吼,而不會(huì)因?yàn)殛P(guān)聯(lián)類型問題而被拒之門外吊档。
case where
原作者說:正是因?yàn)橛蠥ssociated Values特性的存在涡上,才顯得case where特別的甜吩愧。
let provider = LoginProvider.Email(user)
switch provider {
case let .Email(user) where user.isValid():
// login!
break
case let .Email(user) where !user.isValid():
// don’t login!
break
}
case let 首先對(duì)Email進(jìn)行了值綁定(把user對(duì)象抽出來)脐帝,然后使用使用where關(guān)鍵字引入的條件表達(dá)式堵腹,對(duì)邏輯進(jìn)行了一步處理疚顷。switch與枚舉的配合確實(shí)相當(dāng)完美(和Tuples也類似)阀坏。
Functions
說case where還只是一個(gè)鋪墊忌堂,畢竟我們是在這里贊美枚舉嗎,switch再好也不是枚舉的內(nèi)容啊李命。無需感到遺憾封字,枚舉內(nèi)可以定義function,可以整合所有你需要的內(nèi)容笆制。
enum LoginProvider {
case Facebook
case Email(LoginUser)
case Google
case Twitter
func login() {
switch self {
case let .Email(user) where user.isValid():
// login!
break
default:
break
}
}
}
我們?cè)诿杜e中定義方法以后在辆,我們的登錄方案就顯得很完整了,而且非常的簡(jiǎn)潔鸦概。
var lp = LoginProvider.Email(user)
lp.login()
關(guān)于這部分內(nèi)容并沒有結(jié)束窗市,因?yàn)榉磳?duì)意見還沒有出場(chǎng)论熙,如果感興趣可以關(guān)注我的下一篇內(nèi)容:這樣做并不怎么好赴肚。
** 原作者非秤看重枚舉能夠把不同的內(nèi)容整合在一起并體現(xiàn)統(tǒng)一的類型踊跟。如果沒有枚舉的幫助,在統(tǒng)一各種不同的登錄SDK上面拳昌,我們確實(shí)需要在協(xié)議和實(shí)現(xiàn)上面花不少功夫炬藤,而且枚舉提供非常棒的特性沈矿,能夠進(jìn)一步抽象業(yè)務(wù)邏輯羹膳,總之swift的枚舉是非常值得點(diǎn)贊的**