簡體   English   中英

子類化流

[英]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發送到您的收藏!

我需要覆蓋nextatEnd 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM