需要帮助来理解scala代码段

时间:2012-09-21 11:57:51

标签: scala

  

可能重复:
  Can anyone explain how the symbol “=>” is used in Scala

val list = List("abc", "cde", "fg")
list.count (s => s.length == 3)

上面的代码段返回list中长度等于3的字符串元素数。但是我无法理解该片段,因为我无法在这种情况下掌握=>运算符的用法。任何解释都将非常有用。

3 个答案:

答案 0 :(得分:2)

是的,Scala很难理解。我会尽力解释它,不过我可能也不会解决它。

List.count方法将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是应该返回布尔值的代码。您可以根据自己喜欢的名称命名参数,只要它们的顺序正确即可。

当使用迭代集合的方法时,例如countmapeach等,传递的参数将是它迭代的集合中的当前项。

如果你想了解更多关于它的信息,你应该查看正在运行我的Martin Odersky(scala的创建者)的Coursera课程,并将详细介绍这样的细节:https://www.coursera.org/course/progfun

答案 1 :(得分:1)

这只是定义了一个方法,你也可以这样看:

def isValid(s:String) = s.length ==3
list.count(isValid)

因此,当你使用count函数时,你给它一个作为参数函数的条件。

答案 2 :(得分:1)

(我没有看到你发布了另一个(重新措辞)的问题。这是我回答你的第一个问题)

除了传递值/名称之外,=>还用于定义函数文字,这是用于定义函数的替代语法。

示例时间。假设你有一个函数接受另一个函数。这些收藏品很多,但我们会选择filterfilter,当在集合(如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,并返回另一个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-nameby-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中)。