Swift 4.1的部分新特性(一)

2018-02-06蘋果更新了Swift官方文檔-修訂歷史,加入了關(guān)于Swift 4.1的一些新特性:
1. 有條件地遵守協(xié)議
2. 遞歸的協(xié)議約束
3. 增加了條件編譯判斷項(xiàng):canImport()targetEnvironment()

下面詳細(xì)介紹三項(xiàng)特性,所有代碼基于Xcode9.3 beta 4 (9Q127n)調(diào)試運(yùn)行。

1.有條件地遵守協(xié)議(Conditionally Conforming to a Protocol)

按字面意思就是在滿足一定條件時(shí),才認(rèn)為一個(gè)類遵循了某個(gè)協(xié)議,不滿足時(shí)就認(rèn)為該類沒有遵循該協(xié)議。一個(gè)簡(jiǎn)單的例子:

extension Array:TextRepresentable where Element: ProtocolForElement {
    //......
}

在上面例子中,我們擴(kuò)展了Array類,讓其遵循TextRepresentable協(xié)議,但只有在這個(gè)數(shù)組的所有元素都遵循ProtocolForElement協(xié)議時(shí),才有效。就是說(shuō),當(dāng)我們?cè)跀?shù)組中存入了Int類型的元素后,是無(wú)法訪問TextRepresentable協(xié)議所確定的內(nèi)容的(認(rèn)為其并沒有遵循該協(xié)議)。這里where子句所描述的就是條件。where子句描述的并不只有繼承關(guān)系,更多表達(dá)請(qǐng)參考泛型where子句。完整的例子和運(yùn)行結(jié)果如下:

//定義一個(gè)協(xié)議,提供一個(gè)文本描述屬性
protocol TextRepresentable { 
    var textualDescription: String { get }
}

//定義一個(gè)協(xié)議,用于限定子元素。內(nèi)容不重要,暫為空
protocol ProtocolForElement { 
}

//定義一個(gè)遵循了上面元素協(xié)議的類。用于存放到數(shù)組中。
class ClassForElement: ProtocolForElement { 
}

//擴(kuò)展Array類,按條件遵循了TextRepresentable協(xié)議
extension Array:TextRepresentable where Element: ProtocolForElement { 
    var textualDescription: String {
        return "此數(shù)組的元素遵循了ProtocolForElement協(xié)議"
    }
}

let arr1 = [ClassForElement(), ClassForElement()] //建立數(shù)組1,存入遵循ProtocolForElement協(xié)議的元素
print(arr1.textualDescription) //正確輸出:“此數(shù)組的元素遵循了TextRepresentable協(xié)議”

let arr2 = [1,4,7] //建立數(shù)組2,只存入Int元素
print(arr2.textualDescription) //錯(cuò)誤: type 'Int' does not conform to protocol 'ProtocolForElement'

通過(guò)以上例子,我們看到:數(shù)組1由于其元素都遵循ProtocolForElement協(xié)議,所以擴(kuò)展extension Array:TextRepresentable就發(fā)揮了作用,我們可以調(diào)用TextRepresentable協(xié)議所明確的textualDescription方法。而數(shù)組2其元素類型為Int, 并沒有遵循ProtocolForElement協(xié)議,上面的擴(kuò)展就對(duì)其無(wú)效,無(wú)法訪問TextRepresentable協(xié)議所明確的內(nèi)容。

2.遞歸的協(xié)議約束(Recursive protocol constraints)

遞歸在我們平時(shí)的編程中通常是指函數(shù)對(duì)自己的調(diào)用,所以,當(dāng)這個(gè)概念用在協(xié)議定義時(shí),可以理解為協(xié)議中對(duì)自己的訪問。它賦予了協(xié)議可以強(qiáng)制要求屬性、方法參數(shù)和方法返回值也遵循本協(xié)議的能力。舉個(gè)例子:

protocol ExampleProtocol {
    associatedtype T: ExampleProtocol //關(guān)聯(lián)類型為協(xié)議本身
    func doSomething() -> T //要求方法返回的對(duì)象也遵循本協(xié)議
}

以上例子中,我們使用associatedtype關(guān)鍵字定義關(guān)聯(lián)類型時(shí),關(guān)聯(lián)的類型為協(xié)議本身,并將它作為一個(gè)方法的返回類型。以此便限定了方法的實(shí)現(xiàn)者必須返回遵循該協(xié)議的對(duì)象。協(xié)議實(shí)現(xiàn)者例子:

struct Example:ExampleProtocol {
    func doSomething() -> Example { //方法的返回對(duì)象也必須遵循了ExampleProtocol協(xié)議。
        return Example()
    }
}

3.增加了條件編譯判斷項(xiàng)

新增的canImport()可以判定是否可以引入某個(gè)模塊。比如通過(guò)CocoaPods安裝Alamofire后,使用該語(yǔ)句判斷是否可以正確引入:

#if canImport(Alamofire) //判斷是否可引入Alamofire模塊
    class classWithAlamofire{
        //......
    }
#endif

新增的targetEnvironment()可以判定運(yùn)行環(huán)境是否為虛擬機(jī),當(dāng)處于虛擬機(jī)環(huán)境時(shí)返回true, 其他情況返回false。它目前有效的參數(shù)只有simulator:

#if targetEnvironment(simulator)
    class classForSimulator{
        //......
    }
#endif

關(guān)于目前Swift 4.1官方文檔更新的內(nèi)容就介紹到這里。下一篇介紹Xcode9.3 beta release文檔中提及的部分Swift編譯器特性更新。
歡迎關(guān)注我的博客: https://blog.happyyun.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容