[英]Subclassing Stream
我有興趣創建自己的Stream子類,我想知道我應該覆蓋哪些方法(在pharo和Gemstone上部署)。 我有一個包含各種類型的東西的集合,我希望能夠流式傳輸它的一個子集,包含一個類的元素。 我不想復制集合或使用collect:block,因為集合可能很大。 我的第一個用例是這樣的:
stream := self mailBox streamOf: QTurnMessage.
stream size > 1
ifTrue: [ ^ stream at: 2 ]
ifFalse: [ ^ nil ]
關於覆蓋哪些方法的任何指針?
在Smalltalk中,當我們說Stream
我們引用響應基本協議的對象,這些對象由一些方法給出,例如#next,#nextPut:,#content等。所以,在進一步詳細說明之前,我會說這個stream at: 2
,正如你在你的例子中所說,不是一個非常合適的表達方式。 更合適的Stream
表達式
stream position: 2.
^stream next
因此,您必須考慮的第一件事是您是在尋找Stream
還是Collection
。 此基本決策取決於對象必須實現的行為。
如果您決定使用#next枚舉元素,則使用Stream
的子類,即大部分按順序排列。 但是,如果要通過at: index
訪問元素,請使用SequenceableCollection.
的子類為對象建模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"
此外,如果您的流只讀,請將您的類作為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"
(我不認為你的收藏品必須支持at:put:.
)
最近我們遇到了你所描述的相同問題,並決定將我們的對象建模為集合(而不是流。)但是,不管你最終會遵循哪種方法,我認為你應該嘗試兩種方法,看看哪一種更好。 沒有人比Smalltalk系統給你更好的建議。
順便提一下,請注意,如果您有一個(可序) Collection
,您將免費獲得一個Stream
:只需將#readStream
發送到您的收藏!
我需要覆蓋next
和atEnd
。 我Stream
子接管該集合的所有元素塊和收集,並循環block
計算為true。
用法示例:
e := Array with: 1 with: 2 with: 3.
a := QStream collection: e block: [ :i| i odd ].
a next. "1"
a next. "3"
以下是它的核心:
Stream subclass: #QStream
instanceVariableNames: 'collection block index found'
classVariableNames: ''
poolDictionaries: ''
category: 'QDialog-Core'
initialize
super initialize.
index := 1.
self search.
next
| result |
result := found.
self search.
^result.
search
[ index < collection size and: [ (block value: (collection at: index)) not ] ]
whileTrue: [ index := index + 1 ].
self atEnd
ifTrue: [ ^ found := nil ]
ifFalse: [
found := collection at: index.
index := index + 1 ]
atEnd
^ index > collection size
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.