9

Smalltalk で 2 つの文字列を比較しようとしていますが、何か間違っているようです。

このエラーが発生し続けます:

未処理の例外: ブール値以外の受信者です。真実を求めて進みます。

stringOne := 'hello'.
stringTwo := 'hello'.
myNumber := 10.

[stringOne = stringTwo ] ifTrue:[
   myNumber := 20].

私が間違っていることは何か分かりますか?

4

6 に答える 6

17

試す

stringOne = stringTwo 
     ifTrue: [myNumber := 20]`

最初の行に角括弧は必要ないと思います

素晴らしい説明を見つけました。全体はこちら

Smalltalk では、ブール値 (つまり、True または False) はオブジェクトです。具体的には、それらは抽象基底クラス Boolean のインスタンス化、またはむしろその 2 つのサブクラス True と False のインスタンス化です。したがって、すべてのブール値は True または False 型を持ち、実際のメンバー データはありません。Bool には、ifTrue: と ifFalse: という 2 つの仮想関数があり、引数としてコードのブロックを取ります。True と False の両方がこれらの関数をオーバーライドします。True の ifTrue: のバージョンは、渡されたコードを呼び出し、False のバージョンは何もしません (ifFalse: の場合はその逆です)。次に例を示します。

a < b
  ifTrue: [^'a is less than b']
  ifFalse: [^'a is greater than or equal to b']

ちなみに、角括弧内のものは本質的に無名関数です。ただし、Smalltalk ではすべてがオブジェクトなので、それらはオブジェクトです。ここで何が起こっているかというと、引数 b を指定して a の "<" メソッドを呼び出すということです。これはブール値を返します。その ifTrue: および ifFalse: メソッドを呼び出し、どちらの場合でも実行したいコードを引数として渡します。効果はRubyコードと同じ

if a < b then
  puts "a is less than b"
else
  puts "a is greater than or equal to b"
end
于 2009-10-29T02:35:34.037 に答える
5

他の人が言ったように、角かっこの最初のセットを取り除けば、あなたが望むように機能します。

しかし、あなたが遭遇した問題をよりよく説明するには:

[stringOne = stringTwo ] ifTrue:[myNumber := 20]

はメッセージifTrue:をブロックに渡しますが、ブロックはそのメソッドを理解せず、ブール オブジェクトのみが理解します。

最初にブロックを評価すると、真のオブジェクトとして評価され、応答方法を認識します。

[stringOne = stringTwo] value ifTrue:[myNumber := 20]

または、他の人が指摘しているように、あなたが本当にすべきこと:

stringOne = stringTwo ifTrue:[myNumber := 20]

どちらも送信前に評価stringOne = stringTwoされます。trueifTrue:[...]

于 2009-10-29T03:03:28.067 に答える
1

[stringOne = stringTwo]ブール値ではなくブロックです。ブロックが呼び出されると、おそらくブール値になります。ただし、ここではブロックを呼び出していません。代わりに、単にブロックを のレシーバーにしているだけですifTrue

代わりに、次を試してください。

(stringOne = stringTwo) ifTrue: [
    myNumber := 20 ].
于 2009-10-29T02:37:22.457 に答える
0

しかし、私は何か間違ったことをしているようです

VisualWorks を使用している場合、インストールには doc フォルダーが含まれている必要があります。

AppDevGuide.pdfを見てください。VisualWorks を使用したプログラミングに関する多くの情報が含まれており、さらに Smalltalk プログラミングに関する入門情報も多数含まれています。

最初の目次を見て、第 7 章「制御構造」まで、「分岐」または「条件付きテスト」をクリックすると、Smalltalk if-then-else についてすべて説明している PDF の適切なセクションに移動します。そして、あなたが間違っていたことを理解するのに役立つであろう例を示します.

于 2009-10-30T18:02:17.243 に答える
0

次の 50Cent を追加したいと思います。

ブロックは実際には受け渡し可能なラムダであるため、別の良い例は次のメソッドです。

do:aBlock ifCondition:aCondition
    ... some more code ...
    aCondition value ifTrue: aBlock.
    ... some more code ...
    aBlock value
    ...

したがって、ifTrue:/ifFalse: への引数は、実際には他の誰かから来る可能性があります。この種の渡された条件は、「..ifAbsent:」または「..onError:」の種類のメソッドでしばしば役立ちます。

(もともとはコメントを意味していましたが、コード例をフォーマットされていないものにすることができませんでした)

于 2011-05-11T07:55:46.810 に答える
0

比較をブロックする必要がありますか?私は次のように考えていたでしょう:

( stringOne = stringTwo ) ifTrue: [ myNumber := 20 ]

で十分でしょう。

于 2009-10-29T02:36:05.873 に答える