【问题标题】:Smalltalk - Compare two strings for equalitySmalltalk - 比较两个字符串是否相等
【发布时间】:2009-10-29 02:28:20
【问题描述】:

我正在尝试在 Smalltalk 中比较两个字符串,但我似乎做错了什么。

我不断收到此错误:

未处理的异常:非布尔接收器。继续寻找真相。

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

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

知道我做错了什么吗?

【问题讨论】:

    标签: string smalltalk squeak visualworks


    【解决方案1】:

    试试

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

    我认为第一行不需要方括号

    找到了很好的解释。整个thing is here

    在 Smalltalk 中,布尔值(即 True 或 False)是对象:具体来说,它们是抽象基类 Boolean 的实例化,或者更确切地说是它的两个子类 True 和 False。所以每个布尔值都有 True 或 False 类型,并且没有实际的成员数据。 Bool 有两个虚函数 ifTrue: 和 ifFalse:,它们将代码块作为参数。 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 的 "

    if a < b then
      puts "a is less than b"
    else
      puts "a is greater than or equal to b"
    end
    

    【讨论】:

    • 感谢我的安卓伙伴。这就是问题所在。
    • Woof - 我对 Smalltalk 不太熟悉,但我记得方括号是用于评估的,如果您评估 = 运算符,您将不会得到布尔值:)
    • sigh - 想在此处添加代码示例,但格式错误。算了,我加了一个答案……
    【解决方案2】:

    正如其他人所说,如果你去掉第一组方括号,它将按照你想要的方式工作。

    但是为了更好地解释你遇到的问题:

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

    正在将消息ifTrue: 传递给块,块不理解该方法,只有布尔对象可以。

    如果您首先评估该块,它将评估为一个真正的对象,然后它将知道如何响应:

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

    或者正如其他人指出的那样,您应该真正做什么:

    stringOne = stringTwo ifTrue:[myNumber := 20]
    

    在将ifTrue:[...] 发送给它之前,两者都会将stringOne = stringTwo 评估为true

    【讨论】:

      【解决方案3】:

      [stringOne = stringTwo] 是一个块,而不是布尔值。当块被调用时,也许它会产生一个布尔值。但是您没有在这里调用该块。相反,您只是使该块成为ifTrue 的接收者。

      请尝试:

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

      【讨论】:

        【解决方案4】:

        您应该阻止比较吗?我本来以为:

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

        足够了。

        【讨论】:

        • 那里的括号既不必要又不典型。事实上,我发现如果我正在编写需要括号(尤其是嵌套括号)的表达式,我可能会让事情变得过于复杂,并将其重构为命名临时或单独的方法调用。
        【解决方案5】:

        但我似乎做错了什么

        鉴于您使用的是 VisualWorks,您的安装应包括一个 doc 文件夹

        查看 AppDevGuide.pdf - 它包含大量有关使用 VisualWorks 进行编程的信息,甚至包含大量有关 Smalltalk 编程的介绍性信息。

        查看开头的目录表,直到第 7 章“控制结构”,单击“分支”或“条件测试”,您将被带到 pdf 中的相应部分向您介绍有关 Smalltalk if-then-else 的所有信息,并提供有助于您了解自己做错了什么的示例。

        【讨论】:

          【解决方案6】:

          我想添加以下 50Cent:

          由于块实际上是可以传递的 lambda,另一个很好的例子是以下方法:

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

          所以 ifTrue:/ifFalse: 的参数实际上可以来自其他人。这种传入的条件通常在“..ifAbsent:”或“..onError:”这类方法中很有用。

          (原意为注释,但我无法让代码示例未格式化)

          【讨论】:

            猜你喜欢
            • 2021-09-14
            • 2011-04-25
            • 1970-01-01
            • 2013-08-18
            • 2010-12-20
            • 2023-04-10
            相关资源
            最近更新 更多