如何简化scala的函数文字?

hin*_*d_d 5 scala function-literal

我是scala的新手,并试图编写一个函数文字来检查给定的整数是否为奇数.我的第一次尝试是:

val isOdd = (x:Int) => (x & 1) == 1

它工作得很好,而且,由于参数x只在这个函数文字中出现一次,我很想用"_"表示法进一步简化它,如下所示:

val isOdd = ((_:Int) & 1 ) == 1

但这次编译器抱怨:

warning: comparing a fresh object using `==' will always yield false
val isOdd = ((_:Int) & 1 ) == 1

这个警告意味着什么?为什么编译器识别((_ :Int) & 1)为新对象而不是按位运算导致值?有没有办法用"_"表示法编写这个函数文字?

Ken*_*oom 20

问题基本上是Scala需要区分它们

val isOdd = ((_:Int) & 1 ) == 1
Run Code Online (Sandbox Code Playgroud)

你希望等号右边的所有东西都是lambda,而且

val result = collection.map( _ + 1 )
Run Code Online (Sandbox Code Playgroud)

你只希望括号内的东西是lambda

Scala已经决定,当你使用下划线创建一个lambda时,它会选择最里面的一组括号作为lambda的边界.有一个例外:(_:Int)不算作最里面的括号,因为它的目的只是用_占位符对它们进行类型声明的分组.

因此:

val isOdd = ((_:Int) & 1 ) == 1
            ^^^^^^^^^^^^^^
            this is the lambda

val result = collection.map( _ + 1 )
                            ^^^^^^^
                            this is the lambda

val result = collection.map(( _ + 1) / 2)
                            ^^^^^^^^
                            this is the lambda
                            and the compiler can't infer the type of the _

val result = somemap.map(( _ + 1) / 2 * _)
                         ^^^^^^^^
                         this is an inner lambda with one parameter
                         and the compiler can't infer the type of the _
                         ^^^^^^^^^^^^^^^^^
                         this is an outer lambda with one parameter
Run Code Online (Sandbox Code Playgroud)

最后一种情况可以让你做的事情

_.map(_ + 1)
Run Code Online (Sandbox Code Playgroud)

并将其翻译成

x => x.map( y=> y + 1 )
Run Code Online (Sandbox Code Playgroud)


Mar*_*sky 10

只是轻微作弊:

val isOdd = (_: Int) % 2 == 1
Run Code Online (Sandbox Code Playgroud)

:-)

  • +1这不是作弊.事实上,我认为使用`&`是不成熟的.`%`形式更清晰,任何值得盐的编译器(或JIT)都会看到'%2`并将其更改为`&1`,如果它在该操作环境中实际上更快. (2认同)

Deb*_*ski 7

你去:

val isOdd = ((_: Int) & 1) andThen (1 ==)
Run Code Online (Sandbox Code Playgroud)