A function literal is an alternate syntax for defining a function. It's useful for when you want to pass a function as an argument to a method (especially a higher-order one like a fold or a filter operation) but you don't want to define a separate function. Function literals are anonymous -- they don't have a name by default, but you can give them a name by binding them to a variable. A function literal is defined like so:
(a:Int, b:Int) => a + b
You can bind them to variables:
val add = (a:Int, b:Int) => a + b
add(1, 2) // Result is 3
Like I said before, function literals are useful for passing as arguments to higher-order functions. They're also useful for defining one-liners or helper functions nested within other functions.
A Tour of Scala gives a pretty good reference for function literals (they call them anonymous functions).
shareimprove this answer
// switch
assertEnabled = false
// work well
byNameAssert(1 / 0 == 0)
// error
boolAssert(1 / 0 == 0)
bool断言会报错,但是传名不会。
7. 命名空间
scala的字段和方法在同一个命名空间,可以相互覆盖,看码:
trait Rectangular {
// just declare
def topLeft: Point
def bottomRight: Point
def left = topLeft.x
def right = bottomRight.x
def width = right - left
}
上头的特质里头有两个方法没有实现,所以在类混入这个特质的时候编译器会提示你去实现它:
class Rectangle(val topLeft: Point, val bottomRight: Point) extends Rectangular {
}
你只要通过添加相同名字的类参数的方式就可以解决这个问题。
8. 特质(trait)实现可堆叠的改变
待完成
9. 保护的作用域
10. 伴生对象的可见性
11. 模式匹配和样本类
样本类在scala中的实现就是在class关键字之前加上case关键字,看码:
abstract class Expr
case class Var(name: String) extends Expr
case class Number(num: Double) extends Expr
case class UnOp(opertor: String, arg: Expr) extends Expr
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr
object OptionApp {
def show(x: Option[String]) = x match {
case Some(s) => s
case None => "?"
}
def main(args: Array[String]): Unit = {
val capitals = Map("China" -> "beijing", "USA" -> "NewY")
println(show(capitals get "China"))
println(show(capitals get "USA"))
println(show(capitals get "NO"))
}
}
scala中函数使用以下的语法进行定义
2. 函数字面量(Function Literals)
这个词我每次看到都很困惑,我自己一直把它理解为匿名函数或者类lambda表达式之类的,我去google了一下,看到stackoverflow的解释如下:
整体表达的意思也跟我理解的差不多,也就是类似匿名函数,你可以很方便的把它作为高阶函数的参数,或者是把它赋值给某个变量。看码:
赋值给变量的情况:
以上是运行于scala解释器的代码表现。
3. 可变参数
在scala中定义可变参数使用:类型*,看码:
4. 柯里化(curring)
维基百科的解释:
5. 高度抽象的控制结构,借贷模式(loan pattern)
看码:
借贷模式的好处是client代码不用关系太多的事情,骨架的代码由框架或者框架方法来做,上述就是打开和关闭资源了,client只关注自己的业务部分。
下面的代码对上头的进行了currying化:
加上scala对只有一个参数的的话可以用大括号来包围参数来调用,代码就会从:
变成:
看起来更屌?
6. 传名参数(by-name parameter)
看码:
在没有传名参数的时候,外部的断言调用要写成这样:
有了传名调用,就可以写成这样:
而且对比bool断言,传名的好处是在传入参数的时候只是生成了一个函数值,而bool断言传入的是一个bool值,所以要优先被调用,当断言被禁用的时候:
bool断言会报错,但是传名不会。
7. 命名空间
scala的字段和方法在同一个命名空间,可以相互覆盖,看码:
上头的特质里头有两个方法没有实现,所以在类混入这个特质的时候编译器会提示你去实现它:
你只要通过添加相同名字的类参数的方式就可以解决这个问题。
8. 特质(trait)实现可堆叠的改变
待完成
9. 保护的作用域
10. 伴生对象的可见性
11. 模式匹配和样本类
样本类在scala中的实现就是在class关键字之前加上case关键字,看码:
scala编译器自动为你的类添加一些语法上的便捷设定:
编译器自动添加了toString,hashCode,equals方法的自然实现
这样在java中的null引起的编程错误编程饿了scala里的类型错误,如果变量是Option[String]类型的,当你打算用作String的时候,scala就不会编译通过。