Swift tricks系列收集Swift牛逼的patterns和讓你代碼更加Swifty的tricks,持續(xù)更新中……
Phantom Types
在項目中诺祸,某些業(yè)務(wù)是需要按照嚴(yán)格的流程和規(guī)范進(jìn)行的,舉個??
func getSecretData() -> String {
return "secretedata";
}
func encrypt(secretData : String) -> String {
return "encryptdata";
}
func sendEncryptData(encryptdata : String){
// send encrypt data
}
//首先獲取秘密信息
var secretedata = getSecretData()
//對秘密信息加密
var encryptdata = encrypt(secretedata)
//發(fā)送加密信息
sendEncryptData(encryptdata)
上面的例子必須嚴(yán)格按照“獲取信息”->“加密”->“發(fā)送”的流程來肛根,否則就會產(chǎn)生安全問題送漠!
但是程序員是人逆皮,是人就會犯錯誤无畔。如果一個粗心的程序員寫了下面的代碼啊楚,那將會產(chǎn)生災(zāi)難性的后果:
var secretedata = getSecretData()
sendEncryptData(secretedata)
腫么辦?能不能通過代碼來保證流程呢浑彰?Yes, we can!
一般的做法是醬紫的:
struct SecretData {
let secretedata:String
}
struct EncryptData {
let encryptdata:String
}
func getSecretData() -> SecretData {
return SecretData(secretedata:"secretedata");
}
func encrypt(secretData : SecretData) -> EncryptData {
return EncryptData(encryptdata:"encryptdata");
}
func sendEncryptData(encryptdata : EncryptData){
// send encrypt data
}
var secretedata = getSecretData()
var encryptdata = encrypt(secretedata)
sendEncryptData(encryptdata)
這樣我們就能避免粗心程序員造成的錯誤 恭理。因為當(dāng)你試圖執(zhí)行sendEncryptData(secretedata)
的時候,編譯器會報錯郭变!
在上面的方法中颜价,我們定義了兩個struct
,這兩個struct
除了名字不一樣外诉濒,其他都是一模一樣周伦。設(shè)想一下,如果struct
里面的字段稍微多一點未荒,我們的代碼將是這樣的:
struct SecretData {
let secretedata:String
let encyptMehod:String
let encyptKey:String
let from:String
let to:String
......
}
struct EncryptData {
let encryptdata:String
let encyptMehod:String
let encyptKey:String
let from:String
let to:String
......
}
這……就有點不怎么Swifty了专挪。
腫么辦?
Phantom Types片排!
enum Encrypted {}
enum Decrypted {}
struct SecretData<T> {
let secretedata:String
let encyptMehod:String
let encyptKey:String
let from:String
let to:String
}
func getSecretData() -> SecretData<Decrypted> {
return SecretData(secretedata:"secretedata", encyptMehod:"nb", encyptKey:"xxx",from:"agent",to:"gcd");
}
func encrypt(secretData : SecretData<Decrypted>) -> SecretData<Encrypted> {
return SecretData(secretedata:"secretedata", encyptMehod:"nb", encyptKey:"xxx",from:"agent",to:"gcd");
}
func sendEncryptData(encryptdata : SecretData<Encrypted>)
{
// send encrypt data
}
var secretedata = getSecretData()
var encryptdata = encrypt(secretedata)
sendEncryptData(encryptdata)
Encrypted
和Decrypted
是兩個Phantom Type寨腔,我們通過一個范型struct
解決了重復(fù)定義屬性的問題。
PS:看到?jīng)]有case的
enum
不要驚訝率寡,這是Phantom Type的精髓