跳轉到內容

軟體工程師手冊/語言詞典/Smalltalk

來自華夏公益教科書,開放的書籍,開放的世界

Smalltalk

[編輯 | 編輯原始碼]

以下是 維基百科條目.

Smalltalk 是一種完整的過程式面嚮物件語言。

所有引數在概念上都是對物件的引用。然而,所有實現都將小整數表示在指標中,而不是為每個整數分配物理物件。

該語言不要求實現支援正確的尾遞迴,而且沒有任何實現支援。

正是與 Smalltalk 的聯絡使“面向物件”一詞首次出現,儘管第一種面嚮物件語言是 Simula 67。

執行入口點

[編輯 | 編輯原始碼]

Smalltalk 程式通常沒有單個入口點,而是儲存為映像檔案(物件記憶體快照)。啟動後,這些映像檔案將繼續執行在儲存時所執行的操作。

通用語法

[編輯 | 編輯原始碼]

Smalltalk 表示式由訊息傳送和變數賦值組成。

a := b := c + 2 * (x even ifTrue: [y] ifFalse: [z negated]).

訊息傳送可以是以下幾種:

  • 一元(在上面的示例中:even,negated)
  • 二元(+,-,等等)
  • 關鍵字(ifTrue:ifFalse:)

一元訊息繫結最強,然後是二元訊息,最後是關鍵字訊息。二元訊息從左到右進行評估,沒有運算子優先順序。賦值從右到左進行評估。訊息表示式可以加括號。方括號 [] 表示程式碼塊。程式碼塊是一級物件,可以作為引數進行賦值和傳遞。

Smalltalk 註釋以雙引號字元分隔

"This is a comment"

它們可以跨越多行。

變數宣告

[編輯 | 編輯原始碼]

變數必須宣告,但它們沒有型別資訊。方法引數通常在名稱中包含其預期作用或預期類。

臨時變數

| x y total subtotal |

方法引數

addAmount: aDecimalNumber purpose: aString

程式碼塊引數

[:a :b | a < b]

程式碼塊執行

[:a :b | a < b] value:1 value: 2

例項變數和類變數是在類定義訊息中宣告的(不同實現之間的細節有所不同)

Object subclass: #MyClass
  instanceVariableNames: 'name owner additionalData'
  classVariableNames: 'DataRepository'

靜態作用域變數(全域性變數和類變數)透過執行建立它們的表示式來宣告。例如,類定義訊息。

方法宣告/實現

[編輯 | 編輯原始碼]

程式設計師在上編寫方法。是物件可以作為例項製作的柏拉圖模式。在 Smalltalk 中,每個類也被實現為一個物件,支援建立和返回新例項(new)的協議。類具有全域性名稱;所有全域性名稱都以大寫字母開頭。

注意,程式語言 Self 繼承了 Smalltalk 的許多優點,但透過消除類的概念,在概念上更簡單。

Smalltalk 具有全域性變數、例項變數、臨時變數(對方法)和引數(對方法)。程式碼塊也可以有引數。在大多數現代實現中,程式碼塊也可以有自己的臨時變數。還有一種叫做池變數的東西,它們與全域性變數的生存期相同,但只有在明確包含池的類(以及這些類的層次結構)中才能訪問。

在實踐中,池和全域性“變數”通常用於常量。

條件語句

[編輯 | 編輯原始碼]

條件語句是普通訊息表示式。訊息接收者是一個布林值(true 或 false),而引數是程式碼塊。

a < 10 ifTrue: [self handleSmallValue]. 
self hasValidInput
  ifTrue: [self processInput]
  ifFalse: [self displayInputFormatError]

迴圈語句

[編輯 | 編輯原始碼]

迴圈是透過向程式碼塊傳送訊息來完成的

[stream atEnd] whileFalse: [self process: stream nextLine]
[a < limit] whileTrue: [a := a + 1]

對集合的迭代使用 'do:'

anArray do: [:each | self doSomethingWith: each]

計數迴圈看起來像這樣

1 to: 10 do: [:i | Transcript show: i printString; cr]

輸出語句

[編輯 | 編輯原始碼]

由於大多數 Smalltalk 系統不是面向命令列的,因此通常不使用對“stdout”的輸出。但是,Smalltalk 系統通常有一個日誌視窗(Transcript),可以將輸出寫入其中

Transcript show: 'Hello, world!'; cr

標準 Smalltalk 庫包括大量可變集合類的集合:Array、OrderedCollection(在其中有效地從任一端追加或刪除,並且儲存經濟(作為陣列而不是連結列表或樹)、Set、Bag、Dictionary、IdentityDictionary、SortedCollection。集合支援有用的二階函式 collect:(如 Lisp 中的 map)、select:、detect: 和 reject:,以及二階過程 do:。

由於 Smalltalk 是動態型別的,因此它的容器也是動態型別的;它們可以指向任何型別物件的任意組合。

演算法

[編輯 | 編輯原始碼]

<列出該語言原生可用的演算法或演算法列表的引用。列出在該語言不支援的情況下如何合併演算法。或者,如果不可用,請描述這一點。>

垃圾回收

[編輯 | 編輯原始碼]

垃圾回收是自動的。

一些實現支援弱引用。

物理結構

[編輯 | 編輯原始碼]

傳統的 Smalltalk-80 系統由以下部分組成:

  • 執行時引擎(直譯器或 JIT 加上基元和平臺介面)
  • 映像檔案
  • 'changes' 檔案(原始碼和已評估表示式的日誌)
  • 'sources' 檔案(初始映像中方法的原始碼)

現代系統通常將執行時引擎分成可執行檔案和共享庫,並且可能包含用於版本控制系統等的附加檔案。

不要過分執著於你的舊習慣。你可以在 Smalltalk 中編寫 Pascal 風格的程式,但它們不會是好的 Smalltalk 程式。

將行為與最相關的物件保持一致。通常將你的物件擬人化,並以第一人稱編寫註釋,例如

addEntry: anEntry
  "Add anEntry to my list of entries. If the entry conflicts with another entry, I will drop the older one."
  
  entries removeAllSuchThat: [:oldEntry | anEntry conflictsWith: oldEntry].
  entries add: anEntry

網路參考資料

[編輯 | 編輯原始碼]

Smalltalk 免費書籍的一個很棒的資源 [1]

書籍和文章

[編輯 | 編輯原始碼]

<列出可能會有幫助的其他書籍和文章。請包括參考書適合的讀者水平。(初級/中級/高階)>

Goldberg 和 Robson

Byte 雜誌 Smalltalk 專刊,1979 年。

華夏公益教科書