久仰SmallTalk的大名,大概是因为很多design pattern的名著都提到它,并且一说到OOAD也都会提到它老人家。但是我并不知道它是啥子东东,就像谁关心Ada一样。
但是出来混总是需要还的L没想到Martin大叔的“分析模式”竟然是用这个鬼东西写的代码,额的神啊,我只好打起万分的精神,恶补一下。
最不幸的是网上能够找到的关于SmallTalk书,确实比Java少得多的多。找到一本E文的,将就吧。
另外的发现就是ruby号称ruby>(smalltalk+perl),所以有些资料可以在ruby中找到哈。
我的这份Smalltalk的学习笔记,并不是按照Smalltalk进阶的思路整理的,而是在阅读AP第七章的过程中随用到随整理的。看AP是够用了。
变量和赋值
字符 $a $1
字符串变量,用单引号表示。注意在SmallTalk中双引号是注释。所以
‘John’ ‘Martin’这是对的。
A := “John Hunt”这是错的(去死? )
‘a’和$a表示的是不同类的实例,前者对应的Strings;后者对应的Charater。
Symbols
我觉得这就相当于java中的常量
#join week system42
赋值 := (这个和Delphi一样哈)
myName := ‘John Hunt
newIndex := oldIndex
临时变量
|x y z|
x :=5.
y :=6.
Z :=x+y.
Transcript show: z printString.
|
isKindof:类型判断
(anObject isKindOf: String) ifTrue: [...] ifFalse: [...] is an example of Smalltalk's runtime equilivant of "type testing"
集合
Enumerating Collections
do – does the same operation on every element of the collection.
MyCollection do: [:piece | piece reset]
对MyCollection的每个element发送消息reset(其实就是执行reset)
collect – like do: but returns a collection of the results.
select – test every element and returns those which pass.
reject – test every element and returns those which fail.
detect – returns the first element which passes the test
inject:into
inject
在Smalltalk语言中也支持集合的迭代器,如果你要求Smalltalk程序员求数组元素的和,他们会像这样来使用inject函数:
sumOfValues "Smalltalk method"
^self values
inject: 0
into: [ :sum :element | sum + element value]
|
inject是这样工作的,当关联的代码块第一次被调用时,sum被赋给inject的参数值(在这里是0),element取数组第一个元素。第二次和以后调用到代码块时,sum被赋给上次调用代码块时返回的值,这样sum就跑完了全程,inject最终的结果是代码块最后被调用的值。
Dictionary
Dictionary是Set的子类。
at : aKey 对应Java的get(key)
at : aKey put : aValue对应Java的put(key, value)
应用方式:
Code Block
[ :params | <message-expressions> ]
Where :params is the list of parameters the code can take. This means that the Smalltalk code:
[:x | x + 1]可以理解为:f(x) = x + 1
Code Block的调用:
[:x | x + 1] value: 3
can be evaluated as
f(3) = 3 + 1
这是相等于Code Block的定义和调用在一起。
令一种方法是先定义code Block,然后在其它的地方再调用。
anotherBlock := [ :parml :parm2 | | temp |
temp := pannl incorporate: parm2.
temp rehash.
].
|
说明:
1) 定义Code Block,anotherBlock。
2) parml ,parm2是两个参数
3) temp是定义的变量
调用:anotherBlock value: objecfcl value: object2
尽管狠不适应,但是Code Block可以使得代码简洁明了:
positiveAmounts := allAmounts select: [:amt | amt isPositive]
这句话就是从collection allAmounts返回所有positive的单元的集合。amt按我的理解就是对应的每个element。