Swift中結(jié)構(gòu)體如果定義成常量摧茴,原則上來說是不可變的彰导,同一個(gè)方法無論調(diào)用多少遍計(jì)算出來的結(jié)果都是一樣的矢腻。
然而Swift有些結(jié)構(gòu)體初始化的時(shí)候需要傳入一個(gè)閉包鞭衩,做一些事情学搜,這就為常量結(jié)構(gòu)體不可變帶來一些隱患。
比如有一個(gè)迭代器AnyIterator初始化的時(shí)候閉包引入一個(gè)變量value论衍,每次迭代時(shí)變量返回并+1瑞佩。
因?yàn)锳nyIterator引用了外部變量,無論這個(gè)AnyIterator被copy多少份他們都共同通過閉包擁有這個(gè)value變量地址坯台。
實(shí)際項(xiàng)目使用的時(shí)候創(chuàng)建了一個(gè)函數(shù)返回了一個(gè)迭代器炬丸,多次使用之后出了bug,本來很高興以為發(fā)現(xiàn)了swift的bug蜒蕾。
后來仔細(xì)一想發(fā)現(xiàn)是自己使用錯(cuò)了稠炬,其實(shí)我應(yīng)該返回的是一個(gè)序列,而不是一個(gè)迭代器咪啡,通過AnySequence創(chuàng)建AnyIterator首启,把AnyIterator引用的value變量放在AnySequence閉包內(nèi)。
總結(jié): Swift中單純使用結(jié)構(gòu)體的確能保證代碼的安全性撤摸,但是一旦結(jié)構(gòu)體和類或者閉包結(jié)合毅桃,也是很容易出問題的,需要注意准夷。