以_结尾的方法!Scala有特殊意义吗?

aio*_*obe 10 scala naming-conventions

方法以_!诸如此类结尾delete_!或i_is_!具有特殊含义的方式结束?他们只是"名字"吗?他们遵循一些惯例吗?甚至还有bulkDelete_!!.(具体情况是Lift,如果它有所不同.)

Rex*_*err 17

我不确定使用_!和_!!在Lift中的惯例是什么,但这里有一些背景知识.

任何字母数字标识符都可以包含_和添加的符号列表,并且仍然可以解析为单个标识符.例如:

scala> class Example_!@%*!
defined class Example_$bang$at$percent$times$bang
Run Code Online (Sandbox Code Playgroud)

(实际上,如果用反引号包围它,你几乎可以将任何东西解析为标识符 - 例如,如果Java类使用Scala保留字,那么这就是你所做的.或者如果你想在标识符中使用空格.)

但是,编译器只能识别一个符号结尾.如果有一个看起来像getter的方法,那么getter_ =将被解释为setter.(无论你是否真的使用它作为setter都取决于你;无论如何它都将具有setter的语义.)所以

scala> class Q { def q = "Hi"; def q_=(s: String) { println(s.reverse) } }
defined class Q

scala> val q = new Q
q: Q = Q@b5c12e

scala> q.q
res0: java.lang.String = Hi

scala> q.q = "Could use this to set something"
gnihtemos tes ot siht esu dluoC
Run Code Online (Sandbox Code Playgroud)

此外,编译器在任何结束的方法中反转调用者和被调用者的顺序:.这通常出现在列表中:newElement :: existingList实际上是一个调用existingList.::(newElement).所以,例如:

scala> object Caps { def to_:(s: String) = s.toUpperCase }
defined module Caps

scala> "Example" to_: Caps
res40: java.lang.String = EXAMPLE
Run Code Online (Sandbox Code Playgroud)

_+符号的任何其他用法都是惯例.

  • `_`用于从符号字符中分隔单词字符组.所以`foo _ !! _ bar`是一个合法的标识符.如果您不想遵循此规则,或者需要使用保留字,则还可以将其括在反引号中.例如,这对于调用名为`type`的java方法很有用. (3认同)
  • @retronym - 关于反对的好点; 我会补充一点.尝试在REPL中键入`val foo _ !! _ bar = 0`,但.... (2认同)

Dav*_*ith 8

这没什么特别的意思!在斯卡拉的名字.在基于Lisp的语言系列中,!通常用于表示函数具有副作用,这看起来像是惯例.

  • 另一个类似的惯例是使用零参数列表用于无副作用的函数,并使用一个空参数列表用于其他函数列表.例如`gun.model`对`gun.fire()` (2认同)
  • Ruby也使用`!`作为*副作用* (2认同)

psp*_*psp 6

到目前为止奇怪的未提及(虽然与你的问题不是特别相关)是unary_!这是特别对待的.

scala> class A { def unary_! = 5 }
defined class A

scala> !(new A)
res0: Int = 5
Run Code Online (Sandbox Code Playgroud)

  • 它与unary_有更多关系!到底.例如,您可以使用unary_ + (2认同)