Scala编程知识点总结

Scala 2017-01-10

1.课程目标

  • 1.1 目标1:熟练使用scala编写Spark程序
  • 1.2 目标2:动手编写一个简易Spark通信框架
  • 1.3 目标3:为阅读Spark内核源码做准备

2.Scala概述

  • 2.1 什么是Scala

    • Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序。
  • 2.2 为什么学习Scala

    • 优雅,速度快,Scala语言表达能力强,一行代码抵得上Java多行,开发速度快;Scala是静态编译的,所以和JRuby,Groovy比起来速度会快很多。
    • 能融合到Hadoop生态圈:Hadoop现在是大数据事实标准,Spark并不是要取代Hadoop,而是要完善Hadoop生态。JVM语言大部分可能会想到Java,但Java做出来的API太丑,或者想实现一个优雅的API太费劲。

3. Scala编译器的安装

4. Scala基础

  • 4.1 声明变量

    • val:定义的变量值是不可变的,相当于java里用final修饰的变量
    • var:定义的变量是可变得,在Scala中鼓励使用val
    • Scala编译器会自动推断变量的类型,必要的时候可以指定类型

      //变量名在前,类型在后
      val str: String = "wwww.mn1024.cn"
  • 4.2 常用类型

    • Scala和Java一样,有7种数值类型Byte、Char、Short、Int、Long、Float和Double(无包装类型)和一个Boolean类型
  • 4.3 条件表达式

    package cn.mn1024.scala
    
    object ConditionDemo {
      def main(args: Array[String]): Unit = {
        val x = 1
        //判断x的值,将结果赋给y
        val y = if (x > 0) 1 else -1
        //打印y的值
        println(y)
    
        //支持混合类型表达式
        val z = if (x > 1) 1 else "error"
        //打印z的值
        println(z)
    
        //如果缺失else,相当于if (x > 2) 1 else ()
        val m = if (x > 2) 1
        println(m)
    
        //在scala中每个表达式都有值,scala中有个Unit类,写做(),相当于Java中的void
        val n = if (x > 2) 1 else ()
        println(n)
    
        //if和else if
        val k = if (x < 0) 0
        else if (x >= 1) 1 else -1
        println(k)
      }
    }
  • 4.4 块表达式

    package cn.mn1024.scala
    
    object BlockExpressionDemo {
      def main(args: Array[String]): Unit = {
        val x = 0
        //在scala中{}中包含一系列表达式,块中最后一个表达式的值就是块的值
        //下面就是一个块表达式
        val result = {
          if (x < 0){
            -1  
          } else if(x >= 1) {
            1
          } else {
            "error"
          }
        }
        //result的值就是块表达式的结果
        println(result)
      }
    }
  • 4.5 循环

    • 在scala中有for循环和while循环,用for循环比较多
    • for循环语法结构:for (i <- 表达式/数组/集合)

      package cn.mn1024.scala
      object ForDemo {
        def main(args: Array[String]): Unit = {
          //for(i <- 表达式),表达式1 to 10返回一个Range(区间)
          //每次循环将区间中的一个值赋给i
          for (i <- 1 to 10)
            println(i)
      
          //for(i <- 数组)
          val arr = Array("a", "b", "c")
          for (i <- arr)
            println(i)
      
          //高级for循环
          //每个生成器都可以带一个条件,注意:if前面没有分号
          for(i <- 1 to 3; j <- 1 to 3 if i != j)
            print((10 * i + j) + " ")
          println()
      
          //for推导式:如果for循环的循环体以yield开始,则该循环会构建出一个集合
          //每次迭代生成集合中的一个值
          val v = for (i <- 1 to 10) yield i * 10
          println(v)
      
        }
      
      }  
  • 4.6 定义方法和函数

    • def 方法名(参数类型和个数): 返回值类型 = 方法体

      // 方法的返回值类型可以不写,编译器可以自动推断出来,但是对于递归函数,必须指定返回类型
      def m1 (x: Int, y: Int): Int = x * y 
    • val 函数名 = (参数类型和个数) => 函数体

      val f1 = (x: Int, y: Int) => x + y
    • 方法和函数的区别是什么:

      • 函数可以像任何其他数据类型一样被传递和操作,函数是一个对象
      • 函数对象有apply,,curried,,toString,tupled这些方法,而方法不具有这些特性
      • 函数= 方法 _

5. 数组、映射、元祖、集合

  • 5.1 数组

    • 可变: import scala.collection.mutable._

      • val arr = ArrayBuffer[T]()
    • 不可变:import scala.collection.immutable._

      • val arr = new Array[T](数组长度)
    • 数组中如何获取元素

      • arr(index)
    • 遍历数组的元素

      • 增强for循环
      • 好用的until会生成脚标,0 until 10 包含0不包含10
  • 5.2 映射

    • 在Scala中,把哈希表这种数据结构叫做映射
    • 构建映射

      • val map = Map(键->值,键->值....)
      • 利用元组构建 val map = Map((键,值),(键,值),(键,值)....)
    • 注意事项

      • 注意:在Scala中,有两种Map,一个是immutable包下的Map,该Map中的内容不可变;另一个是mutable包下的Map,该Map中的内容可变
      • 注意:通常我们在创建一个集合是会用val这个关键字修饰一个变量(相当于java中的final),那么就意味着该变量的引用不可变,该引用中的内容是不是可变,取决于这个引用指向的集合的类型
  • 5.3 元组

    • 就是用一个()包含的一系列的元素
    • val tuple = ("hadoop", 3.14, 1000)
    • tuple._1
    • tuple._2
  • 5.4 集合

    • Scala的集合有三大类:序列Seq、Set、映射Map
    • 在Scala中集合有可变(mutable)和不可变(immutable)两种类型,immutable类型的集合初始化后就不能改变了(注意与val修饰的变量进行区别)

6. 类、对象、 继承、特质

7. 模式匹配和样例类

  • 匹配字符串
  • 匹配类型
  • 匹配数组
  • 匹配集合
  • 匹配元组
  • 匹配样例类

    • case class:多例的
    • case object:单例的
  • Option类型

    • Some:有值
    • None:无值
  • 偏函数

    • 定义一个偏函数的时候:已经规定好输入和输出参数的类型(范围)

8. Scala中的协变、逆变、非变

  • 协变 C[+T]: 如果A是B的子类,那么C[A]是C[B]的子类。
  • 逆变 C[-T]: 如果A是B的子类,那么C[B]是C[A]的子类。
  • 非变 C[T]: 无论A和B是什么关系,C[A]和C[B]没有从属关系。

9. 上下界

  • 上界: U >: T
  • 这是类型下界的定义,也就是U必须是类型T的父类(或本身,自己也可以认为是自己的父类)。
  • 下界:S <: T
  • 这是类型上界的定义,也就是S必须是类型T的子类(或本身,自己也可以认为是自己的子类)。

10. Scala Actor并发编程

  • Scala中的Actor能够实现并行编程的强大功能,它是基于事件模型的并发机制,Scala是运用消息的发送、接收来实现高并发的。
  • 消息发送方式:

    • ! : 发送异步消息,没有返回值。
    • !!: 发送异步消息,返回值是 Future[Any]。
    • !?: 发送同步消息,等待返回值。(Any)
    • 注意:Any 是所有类的超类,Future[Any]的泛型是异步操作结果的类型。

11. scala中的高阶函数

  • 作为值的函数

    • val list = List(1, 2, 3, 4)
    • val func = (x: Int) => x * 10
    • list.map(func)
  • 匿名函数

    • list.map(x = > x * 10)
  • 柯里化

    • def mm(x: Int,y: Int,z: Int) = x + y + z
    • 使用柯里化定义

      • def mm(x: Int)(y: Int)(z: Int) = x + y + z
  • 闭包

    • 定义函数的时候,此时函数的返回值依赖于不在函数作用域之内的自由变量
    • val y = 10
    • val func =(x: Int)=> x + y
  • 隐式转换和隐式参数

    • 隐式转换
    • 隐式参数

12. akka

  • 利用akka实现2个进程之间的通信
  • 利用akka实现一个简易版的spark通信框架

每一个成功的背后都有无数个无人知晓的黑夜。

因为

夜晚,是超越对手的最佳时机。

===================== 码农1024 =====================#蔺光岭#


本文由 蔺光岭 创作,采用 知识共享署名 4.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论