Scala语言学习总结

1、Scala简介

Scala 是 Scalable Language 的简写,是一门多范式的编程语言。Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序。Scala的编译模型(独立编译,动态类加载)与Java样,所以Scala代码可以调用Java类库。Scala包包括编译器和类库。

2、Scala特性

  • 面向对象:Scala是一种纯面向对象的语言,每个值都是对象。对象的数据类型以及行为由类和特质描述。类抽象机制的扩展有两种途径:一种途径是子类继承,另一种途径是灵活的混入机制。这两种途径能避免多重继承的种种问题。
  • 函数式编程:Scala也是一种函数式语言,其函数也能当成值来使用。Scala提供了轻量级的语法用以定义匿名函数,支持高阶函数,允许嵌套多层函数,并支持柯里化。Scala的case class及其内置的模式匹配相当于函数式编程语言中常用的代数类型。更进一步,程序员可以利用Scala的模式匹配,编写类似正则表达式的代码处理XML数据。
  • 静态类型:泛型类、协变和逆变、标注、参数类型的上下约束、把类别的抽象类作为独享成员、复合类型、引用自己时显示指定类型、试图、多态方法
  • 扩展性:Scala的设计秉承一项事实,即在实践中,某个领域特定的应用程序开发往往需要特定于该领域的语言扩展。Scala提供了许多独特的语言机制,可以以库的形式轻易无缝添加新的语言结构:1、任何方法可用作前缀或后缀操作符2、可以根据预期类型自动构造闭包。联合使用以上两个特性,使你可以定义新的语句而无须扩展语法也无须使用宏之类的元编程特性。
  • 并发性:Scala使用Actor作为其并发模型,Actor是类似线程的实体,通过邮箱发收消息。Actor可以复用线程,因此可以在程序中可以使用数百万个Actor,而线程只能创建数千个。在2.10之后的版本中,使用Akka作为其默认Actor实现。

3、Scala安装

安装Scala要确保安装有JDK并配置好环境变量,Scala下载地址:https://www.scala-lang.org/download/

下载后,双击 msi 文件,一步步安装即可,安装过程你可以使用默认的安装目录。安装好scala后,系统会自动提示,单击 finish,完成安装。

环境配置:

1、右击我的电脑,单击"属性",进入如图所示页面。下面开始配置环境变量,右击【我的电脑】--【属性】--【高级系统设置】--【环境变量】

2、设置 SCALA_HOME 变量:单击新建,在变量名栏输入:SCALA_HOME: 变量值一栏输入:D:\Program Files(x86)\scala 也就是 Scala 的安装目录,根据个人情况有所不同,如果安装在 C 盘,将 D 改成 C 即可。

3、设置 Path 变量:找到系统变量下的"Path"如图,单击编辑。在"变量值"一栏的最前面添加如下的路径: %SCALA_HOME%\bin;%SCALA_HOME%\jre\bin;注意:后面的分号  不要漏掉。

4、设置 Classpath 变量:找到找到系统变量下的"Classpath"如图,单击编辑,如没有,则单击"新建":

  • "变量名":ClassPath
  • "变量值":.;%SCALA_HOME%\bin;%SCALA_HOME%\lib\dt.jar;%SCALA_HOME%\lib\tools.jar.;

注意:"变量值"最前面的 .; 不要漏掉。最后单击确定即可。

5、检查环境变量是否设置好了:调出"cmd"检查。单击 【开始】,在输入框中输入cmd,然后"回车",输入 scala,然后回车,如环境变量设置ok,你应该能看到这些信息。

4、Scala基本语法

   4.1、HelloWorld程序

object HelloWord {

  //def 定义方法
  //main 相当于Java中的main方法
  //args 相当于Java中的main方法的参数名args
  //Array[String] 相当于Java中的main方法的参数类型String[]
  //Unit 相当于于Java中void
  def main(args: Array[String]): Unit = {
    println("Hello word")
  }

}

   4.2、值和变量的声明

  • val声明的变量不可变,相当于Java中的final修饰的变量,自带有getter的方法
  • var声明的变量可变,自带有setter和getter方法

   4.3、Scala常用类型

  • Scala没有区分基本类型和包装类,统一定义为class类:1.toString()生成字符串1
  • Scala7种数值类型和1种boolean类型:Byte-RichByte、Char-RichChar、Short-RichShort、Int-RichInt、Long-RichLong、Float-RichFloat、Double-RichDouble
  • 基本数据类型上使用那些没有提供的方法时,scala会尝试“隐式转换”转换 成增强类型:1.to(10)//生成出Range(1、2、3、4、5、6、7、8、9、10)

   4.4、方法的定义和使用

  //方法定义
  //def 方法么 (参数名1:参数类型,参数名2:参数类型): 返回值类型 ={
  //  return a+b
  //}
  def sum (a:Int,b:Int): Int ={
      a+b
  }
  //带参数无返回值
  def say(a:Int){
    println("接收参数=" + a)
  }
  //无参数也无返回值
  def ask{
    println("无参数无返回值")
  }

  //方法的调用
  def main(args: Array[String]): Unit = {
    sum(3,2)
    say(2)
    ask
  }

   4.5、函数的定义和使用

  //val 函数名:(参数类型1, … , 参数类型n)=>返回值类型 = (T1,…, Tn) => 函数体
  val sum:(Int,Int) => Int = (a,b) =>{
    a+b
  }
  //val 函数名 = (参数名1: 参数类型1, … , 参数名n: 参数类型n) =>函数体
  val sum1 = (a:Int,b:Int) => a+b
  val sum2:(Int,Int) => Int =(a,b) => a+b
  val say= () => {
    print("空参的方法")
  }
  //_占位
  val sum3:(Int,Int) => Int = _+_

  //add方法和函数
  def add(a:Int,b:Int):Int ={
    a+b
  }
  //将方法装化为函数
  val funAdd = add _

  //函数必须有参数列表
  val fun = () => {}

  //函数的调用
  def main(args:Array[String]):Unit={
    println("add方法== " + add(2,3))
    println("add函数== " + funAdd(2,3))
    println(sum(2,3))
    println(sum1(2,3))
    println(sum2(2,3))
    println(sum3(2,3))
  }

   4.6、方法和函数的区别

  • 函数可以赋值给变量,方法不可以
  • 函数的参数列表为空时不可以省略,方法的可以生省略
  • 函数的调用要带括号,否则为函数本身;方法的调用可以不加括号,空参的方法调用时直接使用方法名即可

   4.7、Scala中的循环遍历

  def main(args: Array[String]): Unit = {
    //与Java相同的while和do循环
    //for循环中不支持continue和break

    //yeild会把符合条件的值放到一个集合
    val seq = for(x <- 1 to 10 if x % 2 == 0) yield x;
    println(seq)

    //生成多个生成器
    for (x <- 0 to 10;y <- 0 to 10){
      println( (10 * x) + y)
    }

    //遍历0到10,打印其中的偶数
    for (x <- 0 to 10; if x % 2 == 0) {
      println(x)
    }

    //遍历0到10
    for (x <- 1 to 10) {
        println(x)
    }

    //reverse相当于反向输出
    for(i <- 1 until 10 reverse; if i % 2 == 0) {
      println(i)
    }
    //0 to 10打印10到10,0 until 10打印0到9

    //遍历字符串的字符
    for (x <- "hello word"){
        println("  " + x)
    }

    //根据字符串的长度打印数字
    val str = "hello world";
    for (x <- 0 until str.length ){
      println()
      print( "-" + x)
    }
  }

   4.8、Scala中常见集合使用

  • Scala中的三大集合:序列Seq(List、Vector、Queue)、集合Set、集合Map(当List不适合用时建议用Vector,效率更高)
  • 几乎对所有集合都提供了可变和不可变的版本:1、Scala.collection.immutable.Map//不可变集合。2、scala.collection.mutable.Map//可变集合 
  • 对集合的常见操作:map、flatMap、reduce、distinct、zip
  def main(args: Array[String]): Unit = {
    //map 在列表中的每个元素上计算一个函数,并且返回一个包含相同数目元素的列表。
    val nums = List(1,2,3)
    val numsMap = nums.map(_ * 2)
    println("map = " + numsMap)
    //结果:map = List(2, 4, 6)

    //flatMap 结合了map和flatten的功能。接收一个可以处理嵌套列表的函数,把返回结果连接起来。
    val nums2 = List(List('a','b','c'),List('d','e'))
    val nums21 = List(List(1,2,3),List(4,5))
    val numsFlatmap = nums2.flatMap(x => x.map(x => x))
    val numsFlatmap1 = nums21.flatMap(x => x.map(x => x * 2))
    println("flatMap1 = " + numsFlatmap)
    println("flatMap2 = " + numsFlatmap1)
    //结果flatMap1 = List(a, b, c, d, e)
    //flatMap2 = List(2, 4, 6, 8, 10)

    //filter 移除任何使得传入的函数返回false的元素。
    val nums3 = List(1,2,3,4)
    //val nums3 = List(1.to(10))生成对象为List[scala.collection.immutable.Range.Inclusive] = List(Range 1 to 10)不可变
    val numsFilter = nums3.filter(_ % 2 == 0)
    println("filter = " + numsFilter)
    //结果filter = List(2, 4)

    //zip 两个列表的元素合成一个由元组对组成的列表里 List(1, 2, 3).zip(List("a", "b", "c"))
    val list1 = List(1,2,3,4,5)
    val list2 = List('a','b','c','d')
    val zipList = list1.zip(list2)
    println("zip = " + zipList)
    //结果zip = List((1,a), (2,b), (3,c), (4,d))

    //partition 断言函数的返回值对列表进行拆分
    val pList = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    val p1 = pList.partition(_ % 2 == 0)
    val p2 = pList.partition( _ % 2 == 1)
    println("p1 = " + p1)
    println("p2 = " + p2)
    //结果p1 = (List(2, 4, 6, 8, 10),List(1, 3, 5, 7, 9))
    //p2 = (List(1, 3, 5, 7, 9),List(2, 4, 6, 8, 10))
  }

  4.9、异常处理

  • Scala有类似Java中的try...catch...,在Scala中catch部分可以使用case获取相对应异常做不同的处理,省去多个catch的写法
  • Scala提高了更加优雅的推测执行机制,在scala.util.Try包中,如果成功返回success,如果有异常则返回Failure并携带异常信息
import scala.util.{Try, Success, Failure}
object TryDemo {
  def main(args: Array[String]): Unit = {
    device(1,0) match {
      case Success(x) => println(x)
      case Failure(x) => println(x)
    }
  }
  def device(a:Int,b:Int):Try[Int] ={
      Try(a / b)
  }
}

   4.10、类定义

  • Scala中的方法默认都是public
  • val修饰的字段只有getter方法,var修饰的字段setter和getter方法都有
  • 主构造器的方法必须被实列化
  • 辅构造器使用def this进行定义
  • 每个辅构造器第一行必须调用其他辅构造器或者主构造器
  • Scala可以和Java使用extends关键字、可以将类定义为抽象类abstract
  • Scala父类程序重写子类方法必须加加override、子类实现父类抽象方法时不需要加override
  • Scala中没有static关键字,但object修饰的类所有的方法都是static的,可以将同一个类即声明为object和class,可以有静态和非静态两种方法类型

5、函数式编程思想

  • 函数式编程关心数据的映射,命令式编程关系的式解决问题的思路
  • 函数式编程提倡值不变,如sqrt(x),最终的结果只和输入的x值相关
  • 函数式编程不依赖于外部的状态,也不改变外部的状态,使代码更容易推理,调试和单元测试也更加简单
  • 函数式编程多个线程不共享状态,不会发生资源竞争的问题,更好的支持并发
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值