Lyn*_*ley 2 smalltalk pharo gemstone
我有兴趣创建自己的Stream子类,我想知道我应该覆盖哪些方法(在pharo和Gemstone上部署).我有一个包含各种类型的东西的集合,我希望能够流式传输它的一个子集,包含一个类的元素.我不想复制集合或使用collect:block,因为集合可能很大.我的第一个用例是这样的:
stream := self mailBox streamOf: QTurnMessage.
stream size > 1
ifTrue: [ ^ stream at: 2 ]
ifFalse: [ ^ nil ]
Run Code Online (Sandbox Code Playgroud)
关于覆盖哪些方法的任何指针?
在Smalltalk中,当我们说Stream
我们引用响应基本协议的对象时,通过一些方法给出,例如#next,#nextPut:,#content等.所以,在进一步细节之前我会说stream at: 2
,就像你把在你的例子中,不是一个非常合适的表达方式.更合适的表达Stream
方式是
stream position: 2.
^stream next
Run Code Online (Sandbox Code Playgroud)
所以,你要考虑的第一件事是你是在寻找一个Stream
还是一个Collection
.此基本决策取决于对象必须实现的行为.
使用的子类,Stream
如果你决定要使用#next枚举元素,即主要是在顺序.但是,如果要通过at: index
子类访问元素,请使用子类建模对象SequenceableCollection.
如果您选择流,则必须决定是仅访问它们进行阅读操作还是还要修改其内容.您对问题的描述似乎表明您将只阅读它们.因此,首先要实现的基本协议是
#next "retrieve the object at the following position and advance the position"
#atEnd "answer with true if there are no more objects left"
#position "answer the current position of the implicit index"
#position: "change the implicit index to a new value"
Run Code Online (Sandbox Code Playgroud)
此外,如果您的流将是只读的,请将您的类作为其子类ReadStream
.
如果要继承更高级的方法,还需要实现一些其他额外的消息.一个例子是重新#next:
检索几个连续元素的子集合(其大小由参数给出.)
如果您认为将对象建模为集合会更好,那么您必须实现的基本协议包含以下三种方法
#at: index "retrieve the element at the given index"
#size "retrieve the total number of elements"
#do: aBlock "evaluate aBlock for every element of the receiver"
Run Code Online (Sandbox Code Playgroud)
(我不认为你的收藏必须支持at:put:.
)
最近我们遇到了你所描述的相同问题,并决定将我们的对象建模为集合(而不是流.)但是,不管你最终会遵循哪种方法,我认为你应该尝试两种方法,看看哪一种更好.没有人比Smalltalk系统给你更好的建议.
顺便提一下,请注意,如果您有(可序)Collection
,您将Stream
免费获得:只需发送#readStream
到您的收藏!