Smalltalk - Сравните две строки на равенство - PullRequest
8 голосов
/ 29 октября 2009

Я пытаюсь сравнить две строки в Smalltalk, но, похоже, что-то делаю не так.

Я получаю эту ошибку:

Необработанное исключение: не булев приемник. Приступай к истине.

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

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

Есть идеи, что я делаю не так?

Ответы [ 6 ]

16 голосов
/ 29 октября 2009

Попробуйте

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

Я не думаю, что вам нужны квадратные скобки в первой строке

Нашел отличное объяснение. Всего вещь здесь

В Smalltalk логические значения (т. Е. True или False) являются объектами: в частности, они являются экземплярами абстрактного базового класса Boolean или, скорее, его двух подклассов True и False. Таким образом, каждый логический тип имеет тип True или False и не содержит фактических данных члена. В Bool есть две виртуальные функции, ifTrue: и ifFalse:, которые принимают в качестве аргумента блок кода. И True, и False переопределяют эти функции; Версия ifTrue в True: вызывает переданный код, а версия False ничего не делает (и наоборот для ifFalse :). Вот пример:

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

Кстати, эти вещи в квадратных скобках по сути являются анонимными функциями. За исключением того, что они являются объектами, потому что в Smalltalk все является объектом. Теперь происходит то, что мы вызываем метод «<» с аргументом b; это возвращает логическое значение. Мы вызываем его методы ifTrue: и ifFalse:, передавая в качестве аргументов код, который мы хотим выполнить в любом случае. Эффект такой же, как у кода Ruby </p>

if a < b then
  puts "a is less than b"
else
  puts "a is greater than or equal to b"
end
4 голосов
/ 29 октября 2009

Как уже говорили другие, это будет работать так, как вы хотите, если вы избавитесь от первого набора квадратных скобок.

Но чтобы лучше объяснить проблему, с которой вы столкнулись:

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

передает сообщение ifTrue: в блок, и блоки не понимают этот метод, только логические объекты.

Если вы сначала оцените блок, он оценит истинный объект, который затем будет знать, как реагировать:

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

Или то, что вы действительно должны делать, как указывали другие:

stringOne = stringTwo ifTrue:[myNumber := 20]

оба значения оцениваются от stringOne = stringTwo до true перед отправкой ifTrue:[...] на него.

1 голос
/ 29 октября 2009

[stringOne = stringTwo] - это блок, а не логическое значение. Когда блок вызывается, возможно, это приведет к логическому значению. Но вы не вызываете блок здесь. Вместо этого вы просто заставляете блок быть получателем ifTrue.

Вместо этого попробуйте:

(stringOne = stringTwo) ifTrue: [
    myNumber := 20 ].
0 голосов
/ 11 мая 2011

Я хотел бы добавить следующие 50 центов:

, поскольку блоки на самом деле являются лямбдами, которые можно обойти, другим хорошим примером будет следующий метод:

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

поэтому аргумент ifTrue: / ifFalse: может на самом деле исходить от кого-то другого. Этот тип передаваемых условий часто полезен в методах типа "..ifAbsent:" или "..onError:".

(изначально подразумевался как комментарий, но я не смог получить пример кода без форматирования)

0 голосов
/ 30 октября 2009

но я, кажется, что-то делаю не так

Учитывая, что вы используете VisualWorks, ваша установка должна включать папку с документами .

Посмотрите на AppDevGuide.pdf - в нем много информации о программировании с помощью VisualWorks, а также много вводной информации о программировании на Smalltalk.

Просмотрите таблицу содержания в начале, до Глава 7 «Управляющие структуры» , нажмите «Ветвление» или «Условные проверки», и вы попадете в соответствующий раздел в pdf Вы все о Smalltalk if-then-else и приводите примеры, которые помогли бы вам увидеть, что вы делали неправильно.

0 голосов
/ 29 октября 2009

Стоит ли блокировать сравнение? Я бы подумал, что:

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

будет достаточно.

...