【问题标题】:What does the question mark at the end of a method name mean in Ruby?Ruby 中方法名称末尾的问号是什么意思?
【发布时间】:2010-11-23 16:03:27
【问题描述】:

Ruby 中问号运算符的作用是什么?

有时它看起来像这样:

assert !product.valid?

有时它位于 if 构造中。

【问题讨论】:

标签: ruby


【解决方案1】:

这是一种代码风格约定;它表示一个方法返回一个布尔值(真或假)或一个表示真值(或“真”值)的对象。

问号是方法名称末尾的有效字符。

https://docs.ruby-lang.org/en/2.0.0/syntax/methods_rdoc.html#label-Method+Names

【讨论】:

  • 谢谢,但是这个约定是否意味着它只执行 逻辑 还是会有副作用?有趣的是,这有点像在代码中返回类型的类型语言。
  • 在这种情况下,它是严格的方法命名约定。没有强制执行布尔返回值。仅仅因为方法名称以问号结尾并不意味着该方法必须返回一个布尔值......但它绝对应该返回一个布尔值。但是,Ruby 中 ? 的其他几种用途(是三元运算符,将字符转换为其 ASCII 整数,在 test 中的用法,在 RegEx 等中),其中许多在其他答案中都有介绍在这里。
  • @Jason FYI,即使是强类型语言也有这样的约定。例如,在返回布尔值的 Java 方法中,通常以“is”为前缀,如 isEmpty()isDigit() 等。在 Ruby 中,相同的方法将编写为 empty?digit?,即IMO 好多了。
  • Ajedi32 - 是的,我同意这样命名函数很好,我一直使用is。对于来自 Swift 的人来说,这可能会让人非常困惑,因为那里的问号用于 nullable :)
【解决方案2】:

另请注意 ? 以及一个字符作为自 Ruby 1.9 以来单字符串文字的简写。

例如:

?F # => is the same as "F"

这是在string literals section of the ruby docs 底部附近引用的:

还有一个字符文字表示法来表示单个 字符串,其语法是问号 (?) 后跟 对应于单个字符的单个字符或转义序列 脚本编码中的代码点:

?a       #=> "a"
?abc     #=> SyntaxError
?\n      #=> "\n"
?\s      #=> " "
?\\      #=> "\\"
?\u{41}  #=> "A"
?\C-a    #=> "\x01"
?\M-a    #=> "\xE1"
?\M-\C-a #=> "\x81"
?\C-\M-a #=> "\x81", same as above
?あ      #=> "あ"

在 Ruby 1.9 之前,它返回字符的 ASCII 字符代码。要获得现代 Ruby 中的旧行为,您可以使用 #ord 方法:

?F.ord # => will return 70

【讨论】:

  • 在 ruby​​ 1.9 中它将返回 'F'
【解决方案3】:

在 Ruby 中,返回布尔值的方法以问号结尾是一个惯例。没有比这更重要的了。

【讨论】:

    【解决方案4】:

    在您的示例中,它只是方法名称的一部分。在 Ruby 中,您还可以在方法名称中使用感叹号!

    Ruby 中问号的另一个例子是三元运算符。

    customerName == "Fred" ? "Hello Fred" : "Who are you?"
    

    【讨论】:

    • 要扩展安迪的答案,您还会看到类似的内容:customerName == user.logged_in? ?用户名:“你是谁?”注意双问号
    【解决方案5】:

    可能值得指出的是,?s 只允许在方法名称中,而不是变量中。在学习Ruby的过程中,我假设?指定了一个布尔返回类型,所以我尝试将它们添加到标志变量中,导致错误。这让我一度错误地认为有一些特殊的语法涉及?s。

    相关:Why can't a variable name end with `?` while a method name can?

    【讨论】:

      【解决方案6】:

      在你的例子中

      product.valid?
      

      实际上是一个函数调用,调用了一个名为valid?的函数。按照惯例,某些类型的“条件测试”/布尔函数在函数名称中带有问号。

      【讨论】:

      • answer.gsub!(/function/, 'method')
      【解决方案7】:

      我相信这只是布尔值的约定。有点像说“IsValid”。

      【讨论】:

      • 简洁而精彩的评论特别“有点像说“IsValid”
      【解决方案8】:

      也用在正则表达式中,意思是“前一个字符最多重复一次”

      例如,正则表达式/hey?/ 与字符串“he”和“hey”匹配。

      【讨论】:

        【解决方案9】:

        这也是与来自Kernel#testtest 方法的第一个参数一起使用的常见约定

        test ?d, "/dev" # directory exists?
        # => true
        test ?-, "/etc/hosts", "/etc/hosts" # are the files identical
        # => true
        

        在这个问题中看到here

        【讨论】:

        • test无关,?d"d"的快捷方式。 test 将单字符字符串作为其第一个参数,因此您可以使用 test ?d, "/dev"test "d", "/dev" 调用它。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-27
        • 1970-01-01
        • 2015-11-14
        • 1970-01-01
        • 2018-07-10
        • 1970-01-01
        相关资源
        最近更新 更多