我在scala中阅读了许多使用符号=>
的代码片段,但我从未真正理解它。我试图在互联网上搜索,但找不到任何全面的东西。关于符号如何/可以使用的任何指针/解释都将非常有用。
(更具体地说,我也想知道运算符如何在函数文字中出现)
答案 0 :(得分:16)
除了传递值/名称之外,=>
还用于定义函数文字,这是用于定义函数的替代语法。
示例时间。假设你有一个函数接受另一个函数。这些收藏品很多,但我们会选择filter
。 filter
,当在集合(如List)上使用时,会取出导致您提供的函数返回false的任何元素。
val people = List("Bill Nye", "Mister Rogers", "Mohandas Karamchand Gandhi", "Jesus", "Superman", "The newspaper guy")
// Let's only grab people who have short names (less than 10 characters)
val shortNamedPeople = people.filter(<a function>)
我们可以从其他地方传递一个实际的函数(也许是def isShortName(name: String): Boolean
),但将它放在那里会更好。唉,我们可以用函数文字。
val shortNamedPeople = people.filter( name => name.length < 10 )
我们在这里做的是创建一个接受String的函数(因为people
类型为List[String]
),并返回一个布尔值。很酷,对吧?
此语法用于许多上下文中。假设你想要编写一个接收另一个函数的函数。这个其他函数应该接受一个String,然后返回一个Int。
def myFunction(f: String => Int): Int = {
val myString = "Hello!"
f(myString)
}
// And let's use it. First way:
def anotherFunction(a: String): Int = {
a.length
}
myFunction(anotherFunction)
// Second way:
myFunction((a: String) => a.length)
这就是函数文字的含义。回到by-name
和by-value
,有一个技巧可以强制参数在您想要之前不被评估。经典的例子:
def logger(message: String) = {
if(loggingActivated) println(message)
}
这看起来没问题,但message
实际上是在logger
被调用时进行评估的。如果message
需要一段时间来评估,该怎么办?例如,logger(veryLongProcess())
,其中veryLongProcess()
返回一个String。哎呦?并不是的。我们可以使用我们关于函数文字的知识来强制veryLongProcess()
在实际需要之前不被调用。
def logger(message: => String) = {
if(loggingActivated) println(message)
}
logger(veryLongProcess()) // Fixed!
logger
现在正在接受一个不带参数的函数(因此左侧为裸=>
)。您仍然可以像以前一样使用它,但现在message
仅在使用它时进行评估(在println
中)。