Scala講座:全局變量問題的解決
本文節(jié)選自最近在日本十分流行的Scala講座系列的第七篇,由JavaEye的fineqtbull翻譯。本系列的作者牛尾剛在日本寫過不少有關(guān)Java和Ruby的書籍,相當(dāng)受歡迎。fineqtbull由于時間關(guān)系先翻譯了他認(rèn)為最精彩的第七篇,這篇文章節(jié)選了第七篇中關(guān)于Scala全局變量的描述。
前言
這個連載也持續(xù)了不少的“刺激”內(nèi)容了,這次為還沒有習(xí)慣函數(shù)式編程的讀者寫一些東西。
這樣寫那好像我就是函數(shù)式編程的高手了,其實不是。到現(xiàn)在為止做的盡是Java的工作,從去年開始對于羽生田先生的Scala工作感興趣之后投身于Scala語言以來,一直沒有習(xí)慣函數(shù)式的思考方法,整天在這里面摸爬滾打。看了大量文章,寫了大量代碼之后終于覺得抓住了函數(shù)式編程的重點(diǎn)。
用面向?qū)ο蠛秃瘮?shù)式方法來解決全局變量問題
關(guān)于需要函數(shù)式編程的動機(jī),想從“全局變量問題”這個側(cè)面來考慮一下。
“全局變量問題”是有關(guān)程序維護(hù)方面的問題(圖1)。在編寫多模塊共享全局變量的時候,很難知道在何時哪個模塊使用了該全局變量,程序也就比較容易出錯了。而且,當(dāng)準(zhǔn)備刪除全局變量時,由于不知道是否還有其他模塊在使用它,所以最終把全局變量的定義留在那里不動了。類似情況大家都應(yīng)該碰到過吧。
Scala講座 圖1:全局變量問題
解決“全局變量問題”有兩個方法,一是收窄數(shù)據(jù)的有效范圍;二是使變量被賦值一次后就不能更改。
面向?qū)ο蟮姆绞讲扇〉氖堑谝环N方法。多模塊共有的數(shù)據(jù)被封裝在“對象”中,只有在“對象”內(nèi)部才能夠被使用(圖 2)。
Scala講座 圖2:面向?qū)ο蠓绞较陆鉀Q全局變量問題的方法
函數(shù)式語言采用的是第二種方法,也就是一旦給變量賦值后該變量的值將不會改變(圖3)。
Scala講座 圖3:函數(shù)式語言解決全局變量問題的方法
因此,下述的代碼可以認(rèn)為將數(shù)字“100”綁定在變量“price”上。感覺上就像變量“price”可以像數(shù)字“100”那樣被使用。以前的連載也提到過,Scala中如果用val來定義變量的話,該變量將不能被重新賦值。為了正真的函數(shù)式編程就用val來定義變量吧。
- scala> val price = 100
- price: Int = 100
這樣使變量的再賦值變得不可能之后,就能保證引用的透明性了。也就是說,使用同樣的值作為參數(shù)來調(diào)用同一函數(shù)的情況下,任何時候取得的返回值都是一致的。
例如面向?qū)ο蟮那闆r下,由于對象實例含有內(nèi)部狀態(tài),所以一旦內(nèi)部狀態(tài)改變后,即使使用相同的參數(shù)向同一個對象實例傳遞消息,取得的結(jié)果也有可能不同(圖4)。如果是函數(shù)式編程的話就沒有這種“副作用”了。
Scala講座 圖4:副作用概念圖
【編輯推薦】