Swift tricks-Nonmutating

Swift tricks系列收集Swift牛逼的patterns和讓你代碼更加Swifty的tricks,持續(xù)更新中……

開始今天的話題前,我們先來看幾行代碼:

let unsafemutablepointer : UnsafeMutablePointer<Int>
unsafemutablepointer = UnsafeMutablePointer.alloc(3)
unsafemutablepointer[0] = 1
unsafemutablepointer[1] = 2
unsafemutablepointer[2] = 3
///////////
let intArray : Array<Int> = [1,2,3]
intArray[1] = 3

****上面代碼有什么問題?****

可能你已經(jīng)想到了,編譯器會(huì)報(bào)錯(cuò),因?yàn)槲覀冊(cè)趪L試修改一個(gè)常量數(shù)組。

“If you create an instance of a structure and assign that instance to a constant, you cannot modify the instance’s properties, even if they were declared as variable properties”
“This behavior is due to structures being value types. When an instance of a value type is marked as a constant, so are all of its properties.”

error!.png

那么,另外一個(gè)問題來了:同樣是用下標(biāo)訪問,同樣是值類型(Value Type),為什么UnsafeMutablePointer不會(huì)報(bào)錯(cuò)?

UnsafeMutablePointerArray都是struct,存儲(chǔ)的類型也一樣都是Int,額……


Array:

public subscript (index: Int) -> Element

UnsafeMutablePointer:

public subscript (i: Int) -> Memory { get nonmutating set }

nonmutating是什么東西?!


nonmutating

nonmutating是swift的一個(gè)關(guān)鍵字,它和mutating一樣用來修飾方法,只不過nonmutating一般用來修飾setter方法。
當(dāng)用nonmutating修飾setter方法的時(shí)候,swift編譯器會(huì)知道該方法并不會(huì)改變常量變量,因此不會(huì)報(bào)錯(cuò)。
使用nonmutating有一定的危險(xiǎn)性,因?yàn)樗^了swift編譯器的安全檢查機(jī)制。不過我們可以在合適的情況下使用它,寫出更加靈活的代碼

假設(shè)我們想通過下標(biāo)訪問NSUserDefaults,我們會(huì)這么做:

extension NSUserDefaults {
    subscript(key: String) -> AnyObject? {
        get { return objectForKey(key) }
        set { setObject(newValue, forKey: key) }
    }
}

var defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
defaults["key"] = "value"

不幸的是,defaults是mutable的,這就意味著它可以被別人重新賦值,進(jìn)而引發(fā)問題。使用nonmutating,我們就可以這樣做:

protocol NSUserDefaultsSubscipt {
    subscript(key: String) -> AnyObject? { get nonmutating set }
}
extension NSUserDefaults:NSUserDefaultsSubscipt {
    subscript(key: String) -> AnyObject? {
        get { return objectForKey(key) }
        set { setObject(newValue, forKey: key) }
    }
}
let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
defaults["key"] = "value"

現(xiàn)在再看defaults是不是有點(diǎn)class的感覺?

參考:The why of nonmutating

最后編輯于
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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