val list = List("abc", "cde", "fg")
list.count (s => s.length == 3)
上面的代码片段返回list
长度等于的字符串元素的数量3
。但是我无法理解该片段,因为我无法掌握=>
在这种情况下操作符的用法。任何解释都会非常有帮助。
val list = List("abc", "cde", "fg")
list.count (s => s.length == 3)
上面的代码片段返回list
长度等于的字符串元素的数量3
。但是我无法理解该片段,因为我无法掌握=>
在这种情况下操作符的用法。任何解释都会非常有帮助。
是的,Scala 可能很难理解。我会尽力解释它,尽管我也可能不会正确。
该List.count
方法将返回布尔值的代码作为参数 a block
。
块只是一小段代码,可以通过多种方式创建,例如将代码包含在{ }
在 scala 文档中,这被描述为
def count (p : (A) => Boolean) : Int
所以count
接受一个参数,该参数p
是一个块,它接受一个类型的参数A
并返回一个Boolean
所以在这个例子中:
s => s.length == 3
是一段block
代码。块通常遵循格式
[arguments] => [Code to execute]
所以在这种情况下s
是块的输入,s.length == 3
是应该返回布尔值的代码。您可以随意命名参数,只要它们的顺序正确。
当使用迭代集合的方法时,例如count
, map
,each
等,传递的参数将是它正在迭代的集合中的当前项。
如果您想了解更多相关信息,您应该查看我的 Martin Odersky(scala 的创建者)正在运行的 Coursera 课程,并将详细介绍此类细节:https ://www.coursera.org/course /progfun
这只是定义了一个方法,你也可以这样看:
def isValid(s:String) = s.length ==3
list.count(isValid)
所以,当你使用 count 函数时,你给它一个条件,它是一个函数作为参数。
(我没有看到您发布了另一个(重新措辞的)问题。这是我对您的第一个问题的回答)
不仅仅是传递值/名称,=>
还用于定义函数文字,这是用于定义函数的替代语法。
示例时间。假设您有一个接收另一个函数的函数。集合中充满了它们,但我们会挑选filter
。filter
,当用于集合(如列表)时,将取出导致您提供的函数返回 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 )
我们在这里所做的是创建一个函数,该函数接受一个字符串(因为people
它是 type List[String]
),并返回一个布尔值。很酷,对吧?
此语法在许多情况下使用。假设您要编写一个接收另一个函数的函数。这个其他函数应该接受一个字符串,并返回另一个字符串。
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
and by-value
,有一个技巧,你可以强制一个参数不被评估,直到你想要。经典例子:
def logger(message: String) = {
if(loggingActivated) println(message)
}
这看起来没问题,但message
实际上logger
是在调用时评估的。如果message
需要一段时间来评估怎么办?例如,logger(veryLongProcess())
, whereveryLongProcess()
返回一个字符串。哎呀?并不真地。我们可以利用我们对函数文字的了解来强制veryLongProcess()
在实际需要之前不要调用它。
def logger(message: => String) = {
if(loggingActivated) println(message)
}
logger(veryLongProcess()) // Fixed!
logger
现在正在接受一个不带参数的函数(因此=>
左侧是裸露的)。您仍然可以像以前一样使用它,但现在,仅在使用它message
时才评估(在 中println
)。