像Java,C#等。我如何enum Direction { input, output }在Smalltalk中定义类似的东西?
最简单的方法是让类方方法返回符号或其他基本对象(例如整数)。
因此,您可以将示例编写如下:
Direction class>>input
^ #input
Direction class>>output
^ #output
Run Code Online (Sandbox Code Playgroud)
以及用法:
Direction input
Run Code Online (Sandbox Code Playgroud)
主要缺点是:
^ self name + '::input')更好的方法是创建自己的枚举对象并返回其实例。
该对象应:
=和hash,因此您可以按值比较它们,并使用枚举作为哈希集合(字典)中的键printOn:方法以简化调试它可能看起来像这样
Object subclass: #DirectionEnum
slots: { #value }
classVariables: { }
category: 'DirectionEnum'
"enum accessors"
DirectionEnum class>>input
^ self new value: #input
DirectionEnum class>>output
^ self new value: #output
"getter/setters"
DirectionEnum>>value
^ value
DirectionEnum>>value: aValue
value := aValue
"comparing"
DirectionEnum>>= anEnum
^ self class = anEnum class and: [ self value = anEnum value ]
DirectionEnum>>hash
^ self class hash bitXor: self value hash
"printing"
DirectionEnum>>printOn: aStream
super printOn: aStream.
aStream << '(' << self value asString << ')'
Run Code Online (Sandbox Code Playgroud)
用法还是一样
Direction input.
DirectionEnum output asString. "'a DirectionEnum(output)'"
Run Code Online (Sandbox Code Playgroud)
解决了琐碎方法中提到的问题。
显然,这需要做更多的工作,但是效果更好。如果您有许多枚举,则可以将基本行为移至新的超类Enum,然后DirectionEnum只需要包含类端方法即可。
最接近枚举类型的 Smalltalk 特性是SharedPool(aka PoolDictionary)。因此,如果您要将某个枚举从 Java 移植到 Smalltalk,您可能需要使用SharedPool. 这样做的方法如下:
对于类型中的每个枚举,您将在池中定义一个具有key类型名称和value类型值的关联。
在某些方言中PoolDictionaries是字典,在 Pharo 中它们是SharedPool. 因此,在 Pharo 中,您将所有类型名称声明为类变量。然后将值与初始化方法(类端)中的键相关联。
例如,您可以使用类变量等定义SharedPool命名的子ColorConstants类'Red', 'Green', 'Blue', 'Black', 'White',如下所示:
SharedPool
subclass: #ColorConstants
instanceVariableNames: ''
classVariableNames: 'Red Green Blue Black White'
poolDictionaries: ''
package: 'MyPackage'
Run Code Online (Sandbox Code Playgroud)
要将名称与值相关联,请在以下行中添加类端初始化方法:
ColorConstants class >> initialize
Red := Color r: 1 g: 0 b: 0.
Green := Color r: 0 g: 1 b: 0.
Blue := Color r: 0 g: 0 b: 1.
Black := Color r: 0 g: 0 b: 0.
White := Color r: 1 g: 1 b: 1.
"and so on..."
Run Code Online (Sandbox Code Playgroud)
评估后,ColorConstants initialize您将能够在课堂上使用游泳池
Object
subclass: #MyClass
instanceVariableNames: 'blah'
classVariableNames: ''
poolDictionaries: 'ColorConstants'
package: 'MyPackage'
Run Code Online (Sandbox Code Playgroud)
在MyClass(及其子类)中,您可以按名称引用颜色:
MyClass >> displayError: aString
self display: aString foreground: Red background: White
MyClass >> displayOk: aString
self display: aString foreground: Green background: Black
Run Code Online (Sandbox Code Playgroud)