scala2

来源:互联网 发布:美工职业描述 编辑:程序博客网 时间:2024/05/20 13:20


----------------------模式匹配

1、 match

Scala可以对表达式的类型进行匹配。

for (elem <- List(9,12.3,"Spark","Hadoop",'Hello)){    val str  = elem match{        case i: Int => i + " is an int value."        case d: Double => d + " is a double value."        case "Spark"=> "Spark is found."        case s: String => s + " is a string value."        case _ => "This is an unexpected value."    }println(str)    }
2、标准类库中的 Option 类型用 case 类来表示那种可能存在、也可能不存在的值。当预计到变量或者函数返回值可能不会引用任何值的时候,建议你使用Option类型。Option类包含一个子类Some,当存在可以被引用的值的时候,就可以使用 Some 来包含这个值,例如Some("Hadoop")。而None则被声明为一个对象,而不是一个类,表示没有值。

3、当我们采用getOrElse方法时,如果我们取的"hive"没有对应的值,我们就可以显示我们指定的“No Such Book”,而不是显示None。如下:

  1. scala> val books=Map("hadoop"->5,"spark"->10,"hbase"->7)
  2. scala> val sales=books.get("hive")
  3. sales: Option[Int] = None
  4.  
  5. scala> sales.getOrElse("No Such Book")
  6. res3: Any = No Such Book
  7.  
  8. scala> println(sales.getOrElse("No Such Book"))
  9. No Such Book

在Scala中,使用Option的情形是非常频繁的。在Scala里,经常会用到Option[T]类型,其中的T可以是Sting或Int或其他各种数据类型。Option[T]实际上就是一个容器,我们可以把它看做是一个集合,只不过这个集合中要么只包含一个元素(被包装在Some中返回),要么就不存在元素(返回None)。既然是一个集合,我们当然可以对它使用map、foreach或者filter等方法。比如:

scala> books.get("hive").foreach(println)

可以发现,上述代码执行后,屏幕上什么都没有显示,因为,foreach遍历遇到None的时候,什么也不做,自然不会执行println操作。

 books.get("spark").foreach(println)   //输出  10

-----------------函数定义和高阶函数

函数式编程可以较好满足分布式并行编程的需求(函数式编程一个重要特性就是值不可变性,这对于编写可扩展的并发程序而言可以带来巨大好处,因为它避免了对公共的可变状态进行同步访问控制的复杂问题)。

1、字面量包括整数字面量、浮点数字面量、布尔型字面量、字符字面量、字符串字面量、符号字面量、函数字面量和元组字面量。

函数式编程中,函数的“类型”和“值”也成为两个分开的概念,函数的“值”,就是“函数字面量”。


2、函数的类型和值

def counter(value: Int): Int = { value += 1}
val counter: Int => Int = { (value) => value += 1 }

val counter=(x:Int) => x*2              //采用“=>”而不是“=”,这是Scala的语法要求
def square(x: Int): Int=x*x

3、我们不需要给每个函数命名,这时就可以使用匿名函数,如下:

(num: Int) => num * 2

上面这种匿名函数的定义形式,我们经常称为“Lamda表达式”。“Lamda表达式”的形式如下:

(参数) => 表达式 //如果参数只有一个,参数的圆括号可以省略
scala> val myNumFunc: Int=>Int = (num: Int) => num * 2     //这行是我们输入的命令,把匿名函数定义为一个值,赋值给myNumFunc变量
scala> val myNumFunc = (num: Int) => num * 2    // 可省略类型声明,也就是去掉“Int=>Int”

4、闭包


scala> var more = 1 
scala> val addMore=(x:Int)=>x+more
scala> addmore(10) //输出11
  • scala> more =9
  • more: Int = 9
  • scala> addMore(10)
  • res20: Int = 19 //结论:每个闭包都会访问闭包创建时活跃的more变量。
  • 如上,这个函数定义中,x是函数的传入参数,不会引用函数外部的变量。而闭包则不同,闭包会引用函数外部的变量。我们给more确定具体的值1以后,就让函数addMore中的more变量绑定了具体的值1,不再是“自由变量”,而是被绑定具体的值了,或者说“被关闭”了。调用的时候才被赋值。这样的函数,被称为“闭包”,它反映了一个从开放到封闭的过程。


    5、高阶函数

    一个接受其他函数作为参数或者返回一个函数的函数就是高阶函数。


    6、占位符

    为了让函数字面量更加简洁,我们可以使用下划线作为一个或多个参数的占位符,只要每个参数在函数字面量内仅出现一次。

    1. scala> val numList = List(-3, -5, 1, 6, 9)
    2. numList: List[Int] = List(-3, -5, 1, 6, 9)
    3. scala> numList.filter(x => x > 0 )
    4. res1: List[Int] = List(1, 6, 9)
    5. scala> numList.filter(_ > 0)
    6. res2: List[Int] = List(1, 6, 9)

    从上面运行结果可以看出,下面两个函数字面量是等价的。

    x => x>0
    _ > 0