《快学Scala》——基础

2019-03-16

声明值和变量

  • val定义的值实际上是常量。用var定义的值是变量。在scala中鼓励使用val。不需要给出值或变量的类型,这个信息可以通过初始化的表达式推断出来。(声明值和变量但不做初始化会报错)

  • 在Scala中,变量或函数的类型总是写在变量或函数名称的后面。如下:
    val greeting: String = null
    val greeting: Any = "Hello"
    
  • 在Scala中,仅当同一行中存在多条语句是才需要使用分号隔开。

  • 我们可以将多个值或变量放在一起声明,如下:
    val xmax, ymax = 100  //将xmax和ymax设为100
    var greeting, message: String = null  //greeting和message都是字符串,被初始化为null。
    

常用类型

  • Scala有7种数值类型:Byte、Char、Short、Int、Long、Float和Double,以及一种Boolean类型。这些类型是类, scala并不区分基本数据类型和引用类型。

  • 在Scala中,我们不需要包装类型。在基本类型和包装类型的转换是Scala编译器的工作。举例来说,如果你创建一个Int数组,最终在虚拟机中得到的是一个int[]数组。

  • Scala用底层的java.lang.String类来表示字符串,不过他通过StringOps类给字符串追加了上百种操作。详情见Scala API文档

  • 在Scala中,我们用方法,而不是强制类型转换,来做数值类型之间的转换。举例来说,99.4.toInt得到99。和 Java一样,toString将任意的对象转换成字符串,包含数字的字符串也可以转换成数值,使用toInt和toDouble。

算术和操作符重载

  • Scala的操作符和Java基本上一样,只是有一点特别:这些操作符实际上是方法。例如: a+b 是如下方法调用的简写: a.+(b) 在Scala中几乎可以用任何符号为方法命名。

  • Scala并没有提供++操作,我们需要使用+=1或者-=1来实现递增递减

  • Java中不允许对操作符进行重载,Scala中允许我们自定义操作符。

调用函数和方法

  • 在Scala中使用函数时,不需要从某类调用它的静态方法。如使用数学函数:
    sqrt(2)//将产出1.41421356237307951
    pow(2,4)//将产出16.0
    min(3,Pi)//将产出3.0
    

    这些数学函数是在scala.math包中定义的,你可以用如下语句进行引入:

    Import scala.math._ //在scala中字符“_”是通配符,类似Java中的“*”,
                          //在使用scala开头的包时可以省略scala  
    

    注:不带参数的Scala方法,通常不使用圆括号。

闭包

闭包是一个函数,函数的返回值依赖于函数外部的一个或者多个变量。

object Hello extends App {

  val multiply = (x:Int) => {x * 5}
  // 函数multiply2受到外面的变量factor的影响,所以这两个就形成了一个闭包
  var factor = 5
  val multiply2 = (x:Int) => {x * factor}
  println(multiply2(10)) // 输出:50
  factor = 10
  println(multiply2(10)) // 输出:100
}

柯里化

柯里化是把接收多个参数的函数变成接收一个单一参数的函数,返回一个接收余下参数的新函数。

object Hello extends App {
  def add(x:Int, y:Int) = x + y
  println(add(1,2)) // 输出:3
  // 柯里化后的方法
  def curryAdd(x:Int)(y:Int) = x + y
  println(curryAdd(1)(2)) // 输出:3
  // 模拟柯里化的实现过程
  // 首先是带有一个参数的方法,返回的是一个方法
  def first(x:Int) = (y:Int) => x + y
  val second = first(1)
  val res = second(2)
  println(res) // 输出:3
}