<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    冒號(hào)和他的學(xué)生們(連載15)——數(shù)據(jù)類型

    冒號(hào)和他的學(xué)生們

    ——程序員提高班紀(jì)事


    1. 數(shù)據(jù)類型

    遵禮謂之劬,守法謂之固,此荒國(guó)之風(fēng)也                        ——《荀悅·申鑒》


    待教室平靜下來(lái),冒號(hào)再度開(kāi)腔:“在談?wù)搫?dòng)態(tài)語(yǔ)言之前,最好先澄清一下它與動(dòng)態(tài)類型語(yǔ)言之間的區(qū)別。”

    嘆號(hào)訝然道:“它們不是一回事嗎?一直以為動(dòng)態(tài)語(yǔ)言是動(dòng)態(tài)類型語(yǔ)言的簡(jiǎn)稱呢。”

    “有親戚之名,卻無(wú)血緣之親。名稱上相似,加之動(dòng)態(tài)語(yǔ)言絕大多數(shù)確是動(dòng)態(tài)類型語(yǔ)言,造成混淆實(shí)屬在所難免,但二者之間并無(wú)必然聯(lián)系——?jiǎng)討B(tài)語(yǔ)言不一定是動(dòng)態(tài)類型語(yǔ)言,動(dòng)態(tài)類型語(yǔ)言也不一定是動(dòng)態(tài)語(yǔ)言。”冒號(hào)飛跑的舌頭幾乎絆蒜,同時(shí)把眾人的腦子攪成了一鍋粥。

    見(jiàn)勢(shì)不妙,冒號(hào)改用迂回戰(zhàn)術(shù):“我們不妨再談開(kāi)些,大家對(duì)數(shù)據(jù)類型是如何理解的?”

    逗號(hào)隨口道:“數(shù)據(jù)類型不就是數(shù)據(jù)的種類嗎?”

    眾人暗笑:說(shuō)了跟沒(méi)說(shuō)差不多。

    冒號(hào)說(shuō)道:“數(shù)據(jù)類型包含兩個(gè)要素:一個(gè)是允許取值的集合,一個(gè)是允許參與的運(yùn)算。例如int類型在Java中既定義了介于− 231 231 − 1之間的整數(shù)集合,也定義了該集合上的整數(shù)所能進(jìn)行的運(yùn)算。現(xiàn)在的問(wèn)題是:數(shù)據(jù)類型的意義何在?”

    句號(hào)回答:“限定一個(gè)變量的數(shù)據(jù)類型,就意味著限制了該變量的取值范圍和所參與的運(yùn)算,這從一定程度上保證了代碼的安全性。”

    冒號(hào)追問(wèn):“還有嗎?”

    句號(hào)略作思考后說(shuō):“用戶自定義的數(shù)據(jù)類型,如C中的結(jié)構(gòu)和Java中的類或接口,賦予數(shù)據(jù)以邏輯內(nèi)涵,提高了代碼的抽象性。”

    “精辟!”冒號(hào)贊道,“數(shù)據(jù)類型既有針對(duì)機(jī)器的物理意義,又有針對(duì)人的邏輯意義。前者用于進(jìn)行底層的內(nèi)存分配和數(shù)值運(yùn)算等,后者用于表達(dá)高層的邏輯概念。既然類型如此重要,類型檢查就必不可少了。所謂動(dòng)態(tài)類型語(yǔ)言Dynamic Typing Language),正是指類型檢查發(fā)生在運(yùn)行期間run-time)的語(yǔ)言。”

    “那靜態(tài)類型語(yǔ)言Static Typing Language)自然是類型檢查發(fā)生在編譯期間compile-time)的語(yǔ)言咯。”引號(hào)接話道。

    冒號(hào)回應(yīng):“一般的說(shuō)法是這樣,不過(guò)我更愿意將‘編譯期間’四個(gè)字改為‘運(yùn)行之前’,否則容易讓人誤解為靜態(tài)類型語(yǔ)言一定是編譯型語(yǔ)言(Compiled Language)。”

    問(wèn)號(hào)問(wèn)道:“是否可以這么說(shuō):靜態(tài)類型語(yǔ)言需要變量申明,而動(dòng)態(tài)類型語(yǔ)言則不需要?”

    “這話只對(duì)了一半。”冒號(hào)評(píng)論,“動(dòng)態(tài)類型語(yǔ)言固然不需要顯式的變量申明(Explicit Declaration),一些靜態(tài)類型語(yǔ)言有時(shí)也不需要。典型的如ML、Haskell之類的函數(shù)式語(yǔ)言,編譯器可以通過(guò)上下文來(lái)進(jìn)行類型推斷(type inference)。”

    嘆號(hào)感慨:“動(dòng)態(tài)類型語(yǔ)言不必申明變量,甚至一個(gè)變量在不同地方可以代表不同類型,多省事多方便啊!”

    冒號(hào)微微頷首:“動(dòng)態(tài)類型語(yǔ)言的確有簡(jiǎn)明快捷的優(yōu)勢(shì),并且天然具有泛型(generic)特征,代碼更加靈活。比如,動(dòng)態(tài)類型有一種被稱作鴨子類型(Duck Typing)的形式。”

    逗號(hào)感到有趣:“鴨子類型?很滑稽的名字。”

    “這種類型的思想是:如果一個(gè)對(duì)象既會(huì)走鴨步又會(huì)呷呷叫,何妨將其視作鴨子呢?”冒號(hào)說(shuō)著投影出一段Ruby代碼——


    class Duck                        #會(huì)叫會(huì)游的鴨
        def shout
            puts 
    '呷呷呷'
        end
        def swim
            puts 
    '鴨泳'
        end
    end

    class Frog                         #會(huì)叫會(huì)游的蛙
        def shout
            puts 
    '呱呱呱'
        end
        def swim
           puts 
    '蛙泳'
        end
    end

    def shoutAndSwim(duck)   #讓一只會(huì)叫會(huì)游的家伙邊叫邊游
        duck.shout
        duck.swim
    end

    shoutAndSwim(Duck.
    new)   #讓一只鴨邊叫邊游
    shoutAndSwim(Frog.
    new)    #讓一只蛙邊叫邊游


    冒號(hào)繼續(xù)講解:“在Smalltalk、Python和Ruby等動(dòng)態(tài)類型的OO語(yǔ)言中,只要一個(gè)類型具有shout和swim的方法,它就可以為shoutAndSwim所接受。在Java這種靜態(tài)類型語(yǔ)言中是不可能的,除非鴨和蛙在同一繼承樹(shù)上,或者二者均顯式實(shí)現(xiàn)了一個(gè)包含shout和swim的公用接口。”

    句號(hào)敏銳地指出:“C++是靜態(tài)類型語(yǔ)言,但它的模板也可實(shí)現(xiàn)類似功能,并不需要引入繼承關(guān)系。”

    “非常正確!但請(qǐng)接著看下去。”冒號(hào)又放出一段投影——


    class Cock                                 #會(huì)叫不會(huì)游的雞
        def shout
            puts 
    '喔喔喔'
        end
    end
     
    class Fish                               #會(huì)游不會(huì)叫的魚
        def swim
            puts 
    '自由泳'
        end
    end

    def shoutOrSwim(duck, flag)   #讓一只會(huì)叫或會(huì)游的家伙叫或游
        flag 
    ? duck.shout : duck.swim
    end

    shoutOrSwim(Cock.
    newtrue)       #讓一只雞叫
    shoutOrSwim(Fish.
    newfalse)       #讓一只魚游

    “這里雞沒(méi)有swim的方法,魚沒(méi)有shout的方法。若采用C++的模板,shoutOrSwim是無(wú)法通過(guò)編譯的。但在支持Duck 類型的語(yǔ)言中,只要在運(yùn)行期間不讓雞swim、讓魚shout——除非你突發(fā)奇想——一切平安無(wú)事。”冒號(hào)作了個(gè)OK的手勢(shì)。

    “動(dòng)態(tài)類型語(yǔ)言真是越看越可愛(ài)。”嘆號(hào)簡(jiǎn)直垂涎欲滴了。

    “Duck類型為軟件重用開(kāi)啟了新的窗口,但凡事都是一分為二的。由于Duck類型的接口組合是隱性的,其使用者需要比普通Interface更小心以避免誤用;其維護(hù)者也需要更小心以避免破壞客戶代碼;此外它也可能造成濫用——將會(huì)叫會(huì)游的東西放進(jìn)池塘似乎不算壞主意,但如果一艘輪船趁機(jī)也開(kāi)了進(jìn)來(lái),恐怕就不那么美妙了。”

    眾皆莞爾。

    “再來(lái)看看靜態(tài)類型語(yǔ)言的好處:由于在運(yùn)行之前進(jìn)行了類型檢查,一方面代碼的可靠性增強(qiáng),另一方面編譯器有可能藉此優(yōu)化機(jī)器代碼以提高運(yùn)行效率,同時(shí)相比前者節(jié)省了運(yùn)行期的類型檢查時(shí)間。此外,變量類型的聲明表明了編程者的意圖,有輔助文檔的功效。”冒號(hào)解釋著,“兩種類型的體制可以用兩種法律原則來(lái)類比:靜態(tài)類型檢查類似‘疑罪從有’的有罪推定制——在被證明合法之前是非法的,動(dòng)態(tài)類型檢查類似‘疑罪從無(wú)’的無(wú)罪推定制——在被證明非法之前是合法的。至于如何取舍,套用一句話:‘Static Typing Where Possible, Dynamic Typing When Needed’。”

    問(wèn)號(hào)提出新問(wèn)題:“動(dòng)態(tài)類型語(yǔ)言與弱類型語(yǔ)言有何不同?”

    冒號(hào)喟言:“它們也常常被混為一談,但類型的動(dòng)靜與強(qiáng)弱完全是正交的兩個(gè)概念。前者以類型的綁定(binding)時(shí)間來(lái)劃分,后者以類型的剛性強(qiáng)度來(lái)劃分。通常弱類型語(yǔ)言Weakly-typed Language)允許一種類型的值隱性轉(zhuǎn)化為另一種類型,而強(qiáng)類型語(yǔ)言(Strongly-typed Language)則不允許。舉個(gè)例子,1"2"VB中等于3——第二個(gè)字符串轉(zhuǎn)化為整數(shù);在Javascript中等于"12"——第一個(gè)整數(shù)轉(zhuǎn)化為字符串;在C中則等于一個(gè)不定的整數(shù)值——第二個(gè)字符串作為地址來(lái)運(yùn)算。這樣似乎很有趣很方便,但程序容易藏污納垢,滋生臭蟲(chóng)(bug)。”

    引號(hào)想起:“好像還有一種所謂的類型安全語(yǔ)言?”

    逗號(hào)緊緊抱著頭,仿佛害怕裂開(kāi)。

    “類型按安全性來(lái)劃分,可分為類型安全語(yǔ)言(Type-safe Language)和類型不安全語(yǔ)言(Type-unsafe Language)。一般認(rèn)為強(qiáng)類型語(yǔ)言是類型安全的,弱類型語(yǔ)言是類型不安全的。”冒號(hào)應(yīng)道,“至此,我們已論及數(shù)據(jù)類型的三種劃分方式。值得一提的是,這些劃分并非涇渭分明的,更多的是定性而非定量的描述,甚至沒(méi)有公認(rèn)統(tǒng)一的定義。但了解它們,對(duì)我們?nèi)蘸蟮膶W(xué)習(xí)是有所裨益的。”

    posted on 2008-05-25 19:27 鄭暉 閱讀(2510) 評(píng)論(3)  編輯  收藏 所屬分類: 冒號(hào)和他的學(xué)生們

    評(píng)論

    # re: 冒號(hào)和他的學(xué)生們(連載15)——數(shù)據(jù)類型 2008-06-03 09:51 木東

    寫的非常好,謝謝博主!
    一直在關(guān)注這個(gè)系列
    提個(gè)小建議:

    情景式的教學(xué)確實(shí)確實(shí)很好,也很有創(chuàng)意,但是看的時(shí)候有時(shí)也會(huì)感覺(jué)啰嗦,煩
    能不能在每篇文章加個(gè)小結(jié),把文章的要點(diǎn)以及精辟的句子概括出來(lái),這樣也能夠做到上下兼顧。  回復(fù)  更多評(píng)論   

    # re: 冒號(hào)和他的學(xué)生們(連載15)——數(shù)據(jù)類型 2008-06-03 11:43 鄭暉

    @木東
    您提的意見(jiàn)非常好!事實(shí)上原本的打算是將每篇分為“冒號(hào)課堂”與“句號(hào)筆記”兩部分,后者用于小結(jié)。但因?qū)崟r(shí)創(chuàng)作,暫無(wú)暇顧及后者,今后一定補(bǔ)上!歡迎多提意見(jiàn)!  回復(fù)  更多評(píng)論   

    # re: 冒號(hào)和他的學(xué)生們(連載15)——數(shù)據(jù)類型 2008-08-05 16:13 leweslove

    如果作者寫小結(jié),那是省了讀者寫小結(jié)了  回復(fù)  更多評(píng)論   

    導(dǎo)航

    統(tǒng)計(jì)

    公告

    博客搬家:http://blog.zhenghui.org
    《冒號(hào)課堂》一書于2009年10月上市,詳情請(qǐng)見(jiàn)
    冒號(hào)課堂

    留言簿(17)

    隨筆分類(61)

    隨筆檔案(61)

    文章分類(1)

    文章檔案(1)

    最新隨筆

    積分與排名

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: CAOPORN国产精品免费视频| 91嫩草亚洲精品| 中文字幕亚洲图片| 伊人久久亚洲综合影院| 精品国产麻豆免费网站| 免费理论片51人人看电影| 午夜视频免费成人| 日韩免费无码一区二区视频| 日韩免费毛片视频| 亚洲av午夜成人片精品电影 | 爱爱帝国亚洲一区二区三区| 亚洲中文字幕乱码AV波多JI| 亚洲中文字幕久久久一区| 亚洲日韩av无码中文| 亚洲乱妇老熟女爽到高潮的片| 亚洲色偷偷色噜噜狠狠99| 亚洲美国产亚洲AV| 男人免费视频一区二区在线观看| 一区二区免费国产在线观看| 国产中文字幕在线免费观看| 99在线观看视频免费| 中文字幕无码播放免费| 夜夜爽免费888视频| 国产免费人成在线视频| 亚洲欧洲一区二区三区| 亚洲高清国产拍精品26U| 亚洲成人黄色网址| 久久夜色精品国产噜噜亚洲a| 综合偷自拍亚洲乱中文字幕| h在线看免费视频网站男男| 国产婷婷成人久久Av免费高清| 99热在线观看免费| 24小时日本在线www免费的| 亚洲国产天堂久久久久久| 久久综合日韩亚洲精品色| 亚洲丰满熟女一区二区v| 日日摸日日碰夜夜爽亚洲| 99re6在线精品免费观看| 亚洲视频在线观看免费视频| 国产成人无码区免费A∨视频网站 国产成人涩涩涩视频在线观看免费 | 亚洲三级高清免费|