scala-语法简介

Scala

本文档由博主参考慕课网学习Scala进击大数据Spark生态圈整理

1. 初始Scala

  • https://zh.wikipedia.org/wiki/Scala

  • 面向对象、函数式编程、基于Java虚拟机

  • https://www.scala-lang.org/

  • Scala combines object-oriented and functional programming in one concise, high-level language. Scala’s static types help avoid bugs in complex applications, and its JVM and JavaScript runtimes let you build high-performance systems with easy access to huge ecosystems of libraries.

  • Spark、Kafka、Flink生态圈

    • 优雅、开发速度、融合到生态圈
  • Java 1.8、Scala 2.11.8

  • Scala使用入门

    • 不强求每行以;结尾

    • scalac、scala

    • object HelloWorld {
         def main(args: Array[String]) {
           println("hello world")
         }
       }
      

2. Scala入门

  • val: 类似于java中的final (值)、var (变量)

  • Scala基本数据类型

    • Byte/Char、Short/Int/Long/Float/Double、Boolean

    • val a = 10.asInstanceOf[Double]
      val b = 10.isInstanceOf[Int]
      
  • lazy在Scala中的使用

    • lazy val a = 1
      
  • Scala常见的IDE

    • IDEA、Eclipse、NetBeans
  • IDEA整合Maven构建Scala应用

3. Scala函数

  • 函数的定义和使用

    • def max(x: Int, y: Int): Int = {
        if (x > y)
        	x
        else
        	y
      }
      
    • 方法体最后一行作为返回值不需要return

      没有入参的函数在调用时括号是可以省略的

  • 默认参数的使用

    • 在函数定义时允许指定参数的默认值
  • 命名参数的使用

    • def speed(distance: Double, time: Double): Double = {
        distanec/time
      }
      speed(100, 10)
      speed(distance=100, time=10)
      speed(time=10, distance=100)
      
  • 可变参数的使用

    • def sum(numbers: Int*) = {
        var res = 0
        for (number <- numbers) {
          res += number
        }
      }
      
  • 条件表达式

    • val a = if (x > 0) true else false
      
  • 循环表达式

    • 1 to 10  // 左闭右闭
      1.to(10)
      
      Range(1, 10)  // 左闭右开
      
      1 until 10  // 左闭右开
      1.until(10)
      
      for (item <- arr) {
      	println(item)
      }
      
      arr.foreach(item ==> println(item))
      
      x = 0
      while (x > 10) {
        println(x)
        x += 1
      }
      

4. Scala面向对象

  • 面向对象概述

    • 封装、继承、多态 (父类引用指向子类特征)
  • 类的定义和使用

    • 占位符_

    • var a1: Int = _  // 0
      var a2: String = _  // ""
      var a3: Double = _  // 0.0
      
      val b: Int = _  // 值不能使用占位符
      
  • 主构造器和附属构造器

    • class Person(val name: String, val age: Int) {
        println("Person constructor enter ...")
        val school = "xidian"
        var gender = _
        println("Person constructor leave ...")
        
        def this(name: String, age: Int, gender: String) {
          this(name, age)  // 附属构造器的第一行代码必须调用主构造器或者其他附属构造器
          this.gender = gender
        }
      }
      
  • 继承

    • class Student(name: String, age: Int, val major; String) extends Person(name, age) {
        println("Person Student constructor leave ...")
        println("Person Student constructor leave ...")
      }
      
  • 重写

    • override val school = "beihang"
      override def toString: String = "override def toString"
      
    • 使用override对父类的属性和方法进行重写

  • 抽象类

    • 类的一个或多个方法没有完整实现 (只有定义没有实现)

    • abstract class Person {
        val name: String
        val age: Int
        def speak
      }
      
      class Student extends Person{
        override def speak: Unit {
          println("speak")
        }
        override val name: String = _
        override val age: Int = _
      }
      
  • 伴生类和伴生对象

    • 若class和object同名 则称class为object的伴生类 object为class的伴生对象

    • apply方法

    • object ApplyApp {
        def main(args: Array[String]): Unit {
          for (i <- 1 to 10) {
            ApplyTest.incr
          }
          println(ApplyTest.count)  // 10 说明object本身就是一个单例对象
          
          val a = ApplyTest()  // 类名(): 调用的是Object中的apply方法
          
          val b = new ApplyTest()
          println(b)
          b()  // 对象(): 调用的是Class的Apply
        }
      }
      
      class ApplyTest {
         def apply() {
          println("Class ApplyTest apply")
        }
      }
      
      object ApplyTest {
        println("Object ApplyTest enter ...")
        
        var count = 0
        def incr = {
          count += 1
        }
        
        // 最佳实践: 在object的apply方法中new class
        def apply() {
          println("Object ApplyTest apply")
          new ApplyTest
        }
        
        println("Object ApplyTest leave ...")
      }
      
  • case class

    • def main(args: Array[String]): Unit {
        println(Dog("wangcai").name)  // wangcai
      }
      
      // case class不用new
      // 通常用在模式匹配里
      case class Dog(name: String)
      
  • trait

    • xxx extends ATrait with BTrait

5. Scala集合

  • 定长数组

    • object ArrayApp extends App {
        println("ok")
        
        val a = new Array[String](5)
        // a.length
        // a(1) = "hello"
        
        val b = Array("hadoop", "spark", "storm")  // object中的apply方法
        b(1) = "scala"  // val b指的是数组的指针不变
        
        val c = Array(1, 2, 3, 4, 5, 6)
        // c.sum/c.min/c.max
        // c.mkString("")
        // c.mkString(",")
        // c.mkString("<", ",", ">")
      }
      
  • 变长数组

    • object ArrayApp extends App {
        val a = scala.collection.mutable.ArrayBuffer[Int]()
        a += 1  // 1
        a += 2  // 1 2
        a += (3, 4, 5)  // 1 2 3 4 5
        a ++= Array(6, 7, 8)  // 1 2 3 4 5 6 7 8
        a.insert(0, 0)  // 0 1 2 3 4 5 6 7 8
        a.remove(0, 3)  // 3 4 5 6 7 8
        a.trimStart(2)  // 5 6 7 8
        a.trimEnd(2)  // 5 6
        a.toArray  // 转成定长Array
      }
      
  • List

    • Nil: scala.collection.immutable.Nil.type = List()

    • val l = List(1, 2, 3, 4, 5)
      l.head  // 1
      l.tail  // List(2, 3, 4, 5)
      
      val l2 = 1::Nil  // 一头一尾 List(1)
      
      val l3 = scala.collection.mutable.ListBuffer[Int]()
      l3 ++= List(1, 2, 3, 4, 5, 6)
      l3 -= 1  // 2 3 4 5 6
      l3 --= List(6, 7)  // 2 3 4 5
      l3.toList  // 转成定长List
      l3.toArray
      l3.tail.head  // 3
      
      def sum(nums: Int*):Int {
        if (nums.lenght == 0) {
          0
        } else {
          nums.head += sum(num.tail:_*)  // 将Seq转为可变参数
        }
      }
      
  • Set

    • val s = Set(1, 1, 2, 3)  // Set(1, 2, 3)
      

6. 模式匹配

  • 基本数据类型模式匹配

    • import scala.util.Random
      
      object MatchApp extends App {
        val age = 18
        val names = Array("A", "B", "C")
        val name = names(Random.nextInt(names.length))
        name match {
          case "A" => println("a")
          case "B" => println("b")
          case "C" => println("c")
          case _ if (age==18)  => println("no idea (conditional)")
          case _ => println("no idea")
        }
      }
      
  • Array模式匹配

    • def greeting(array:Array[String]): Unit {
        array match {
          case Array("zisheng") => println("hi zisheng")
          case Array(x, y) => println("hi " + x + " and " + y)
          case Array("zisheng", _*) => println("hi zisheng and everybody")
          case _ => println("hi everybody")
        }
      }
      
  • List模式匹配

    • def greeting(list:List[String]): Unit {
        list match {
          case "zisheng"::Nil => println("hi zisheng")
          case x::y::Nil => println("hi " + x + " and " + y)
          case "zisheng"::tail => println("hi zisheng and everybody")
          case _ => println("hi everybody")
        }
      }
      
  • 类型模式匹配

    • def matchType(obj:Any): Unit {
        obj match {
          case i:Int => println("Int")
          case s:String => println("String")
          case m:Map[_, _] => println("Map")
          case _ => println("Other types")
        }
      }
      
  • Scala异常处理

    • try {
        val a = 10/0
      } catch {
        case e:ArithmeticException => println("divided by zero")
        case e:Exception => println(e.getMessage)
      } finally {
        // 释放资源文件 一定能执行
      }
      
  • case class模式匹配

    • class Person
      case class CEO(name:String) extends Person
      case class Employee(name:String) extends Person
      case class Others(name:String) extends Person
      
      def caseClassMatchApp(person:Person):Unit {
        person match {
          case CEO(name) => println("CEO")
          case Employee(name) => println("Employee")
          case _ => println("Others")
        }
      }
      

7. Scala函数高级操作

  • 字符串高级操作

  • 匿名函数

    • val incByOne = (x:Int) => x + 1
      def add = (x:Int, y:Int) => x + y
      
  • curry函数

    • def sum(x:Int)(y:Int) = x + y
      
  • 高级函数

    • val l = List(1, 2, 3, 4, 5, 6, 7)
      
      // map: 逐个操作集合中的每个元素
      l.map((x:Int) => x + 1)
      l.map((x) => x + 1)
      l.map(x => x + 1)
      l.map(_ + 1).foreach(println)
      
      //filter
      l.filter(_ > 4)
      
      // take: 取集合中的前几个元素
      l.take(2)
      
      //reduce
      l.reduce(_ + _)
      
      //flatten
      List l2 = List(List(1, 2), List(3, 4))
      l2.flatten  // List(1, 2, 3, 4)
      l2.flatMap(_.map(_*2))  // List(2, 4, 6, 8)
      
  • 偏函数

    • 被包在花括号内没有match的一组case语句

8. Scala隐式转换

  • 为已存在的第三方类添加一个新的方法

  • import java.io.File
    
    object ImplicitApp extends App {
      // 定义隐式转换函数即可
      implicit def man2Superman(man:Man): SuperMan = new SuperMan(man.name)
      val man = new Man("zisheng")
      man.fly()
      
      implicit def file2RichFile(file:File): RichFile = new RichFile(file)
      val file =. new File("../data/hello.txt")
      val txt = file.read  // File本身没有read()方法
      println(txt)  // 打印txt文件中的内容
      
    }
    
    class Man(val name: String): Unit {
      def eat() = {
        println(s"Man $name eat")
      }
    }
    
    class SuperMan(val name: String): Unit {
      def fly() = {
        println(s"Superman $name fly")
      }
    }
    
    class RichFile(val file: File) {
      def read() = {
        scala.io.Source.fromFile(file.getPath).mkString
      }
    }
    
  • 隐式转换切面封装

    • 将implicit统一封装封装至一个文件用时import即可
  • 隐式参数

    • def testParam(implicit name:String): Unit = {
        println(name)
      }
      
      // testParam("zisheng")
      
      implicit val name = "zisheng"
      testParam  // 运行成功
      
  • 隐式类

    • object ImplicitClassApp extends App {
        implicit class Calculator(x:Int) {
          def addTwo(y:Int) = x + y
        }
        println(1.addTwo(2))  // 3
      }
      

9. Scala操作外部数据

  • Scala读取文件及网络数据

    • import scala.io.Source
      
      object FileApp extends App {
        val file = Source.fromFile("../data/hello.txt")
        def readFileLine(): Unit = {
          for (line <- file.getLines()) {
            println(line)
          }
        }
        readFileLine
        
        def reafFileChar(): Unit = {
          for (ele <- file) {
            println(ele)
          }
        }
        reafFileChar
        
        def readNet(): Unit = {
          val net = Source.fromURL("http://www.baidu.com")
          for (line <- net.getLines()) {
            println(line)
          }
        }
      }
      
  • Scala读取MySQL数据库

  • Scala读取XML文件

    • import scala.xml.XML
      

10. 项目实战

  • 项目概述
    • Spring Boot + Spring Data JPA + Scala/Java混编

你可能感兴趣的:(Scala)