1

これが期待どおりに機能しない理由を誰かが説明できますか?

add: rhsKey
myUnits includesKey: rhsKey
            ifTrue: myUnits put: (myUnits at: rhsKey) + 1 at: rhsKey 
            ifFalse: myUnits add: rhsKey -> 1.

実行例:

ut := UnitTracker の名前: 'test'。

ut add: 'seconds'.

ut add: 'seconds'.

ut add: 'seconds'.

ut add: '分'.

最初のラウンドで ifTrue を実行し続けます。

4

3 に答える 3

7

ifTrue:ifFalse:[ ]ブロックを引数として受け入れます。ブロック内の true および false で実行するコードをカプセル化しない場合、 への呼び出しの前に実行されifTrue:ifFalse:ます。

myUnits includesKey: rhsKeyまた、括弧で囲む必要があります( )。そうしないと、実際に送信しようとしているメッセージについてコンパイラが混乱するためです。

実際、myUnits に効果的に送信したため、そのコードに対して DoesNotUnderstand 例外が発生しなかったことに驚いていますincludesKey:ifTrue:put:at:ifFalse:add:

おそらく意図したとおりにブラケットを追加すると、次のようになります。

add: rhsKey
  (myUnits includesKey: rhsKey)
        ifTrue: [ myUnits put: (myUnits at: rhsKey) + 1 at: rhsKey ]
        ifFalse: [ myUnits add: rhsKey -> 1. ]

だから今ifTrue:ifFalse:、の結果に送られていますmyUnits includesKey: rhsKey

于 2013-06-11T05:18:46.777 に答える
2

キーワード構文を理解したら、次のat:ifAbsent:ように使用できる辞書でメッセージを学習/模倣することをお勧めします。

myUnits at: rhsKey put: (myUnits at: rhsKey ifAbsent: [0]) + 1  
于 2013-06-11T08:21:27.793 に答える