书名:Scala 学习手册/(美)Swartz,J. 著;苏金国等译。–北京:中国电力出版社,2016.2

第1章 概述

  1. 输出:println("hello world!"),String 字符为双引号,Char 字符为单引号
  2. REPL:Read,Evaluate,Print,Loop.可以跨会话存储
  3. up 箭头:上一行命令
  4. 每一行的输出resultREPL 会用一个常量变量保存:res0,res1,...
  5. 运行scala文件hello.scala
    1. 交互环境中输入 scala> :load hello.scala
    2. 命令行:scala hello.scala
  6. 退出::q

第2章 数据类型(数值类型:Int,Double,非数值类型:String,Char

  1. 字面量值(不可重新赋值):scala> val x:Int=10,不可变有类型的存储文件,用关键字val(value),类型可省略scala> val x = 10
  2. 变量:scala> var a:Double=2.73,关键字var(variable),类型可省略scala> var a=2.73
  3. 字符串
    val approx = 355/113f
    println("Pi,using 355/113,is about "+approx+".")
    println(s"Pi,using 355/113,is about $approx.")    //内插法
    
  4. 字符串内插(替代格式printf,难读,输出可格式化)
    val item = "apple"
    println(s"How do you like them ${item}s?")
    println(s"Fish n chips n ,${"pepper "*3}salt")  // 字符串乘法println(f"I wrote a new $item%.3s today")
    println(f"Pi,using 355/113,is about ${355/113.0}%.5f.")   //内插法
    
  5. 正则表达式
    "Froggy went a' courting" matches ".* courting" //Ture or False"milk,tea,muck" replaceAll ("m[^ ]+k","coffee")
    "milk,tea,muck" replaceAll ("m[^ ].k","coffee")"milk,tea,muck" replaceFirst ("m[^ ]+k","coffee")
    "milk,tea,muck" replaceFirst ("m[^ ].k","coffee")// 捕获组:小括号定义,输入至少包括一个匹配值
    val input = "Enjoy this apple 3.14159 times today"
    val pattern = """.* apple ([\d.]+) times .*""".r // r 为字符串操作符
    val pattern(amountText) = input
    val amount = amountText.toDouble
    
  6. 类型操作(每个类型都属于一个对象)
    1. scala> 5.asInstanceOf[Double]:val/var 类型转换(尽量用第五条)
    2. scala> nada.getClass:val/var 查看类型
    3. val/var 类型确认:scala> nada.isInstanceOf[Unit]
    4. val/var 散列码: scala> "A".hashCode
    5. val/var 转换函数:toString/toByte/toFloat/...
  7. 元组:包含两个以上值得有序容器,值类型可不同,不可迭代但可通过下标访问。类似关系型数据库中得一行
    // 元组,下标从1开始
    val info = (5,"Korben",true)
    val name = info._2val red = "red"->"0xff0000" // 利用关系操作符创建2元组
    val reversed = red._2 -> red._1
    

注:

1. 值优先于变量,因为值可以为代码带来稳定性和可预测性。
2. 类型为Double 的变量可以赋 Int 值,因为Int数可以自动转换为Double 数。
3. 变量命名建议:`camel case`驼峰命名
4. 字符串支持三重双引号
5. Scala 不支持其他类型到Boolean 的自动转换,非Null 字符不会计算为True,0也不等于False
6. &&与||很懒,第一个参数可以出结论,不在计算第二个参数。&与| 会对两个参数都做检查
7. Unit 字面量:`scala> val nada=()`,通常用来定义函数和表达式

第3章 表达式 和 条件式

表达式

  1. 表达式:scala> val x=5*20;val amount = x+10,字面量val/var 也是一种表达式

  2. 表达式块:scala> val amount = {val x=5*20;x+10}块中最后一个表达式最为块得返回值。

    1. 表达式块分号,可用换行替代
    2. 表达式块可以嵌套scala> {val a=1;{val b=a*2;{val c=b+4;c}}}
    // 结果可以赋值给变量
    val x = -3
    if (x>0) {println("This is a positive number!")
    } else if (x==0){println("This is zero")
    } else {println("This is a negative number !")
    }
    
  3. if…else 表达式块:scala> val max = if(5>3) {val x=4*2;x+2} else 2

  4. 匹配表达式(match expressions):类似 switch

    // 匹配表达式
    val status=500
    val message = status match {case 200 => "ok"case 400 => println("ERROR - we called the service incorrectly");"error"case 500 => {println("ERROR - the service encountered an error");"error"}
    }
    // 模式替换式 pattern alternative
    val day = "MON"
    val kind = day match {case "MON"|"tue"|"wed"|"thu"|"fri" => "weekday"case "sat"|"sun" => "weekend" case unexpected => unexpected + " is not expected!" // 除了通配符,匹配值还可以获取
    }
    
  5. 通配模式匹配

    //值绑定
    val message="ok"
    val status = message match {case "ok" => 200case other => println(s"could not parse $other");-1
    }//other 为case 块定义,并赋值为 message
    //通配符
    val message="Tom"
    val status = message match {case "ok" => 200case _ => println(s"could not parse $message");-1
    }//_ 通配符,可以匹配任意值,右侧不可访问.若需要访问,可直接访问输入// 类型模式
    for (elem <- List(9,12.3,"spark","hadoop",'hello)){println("current value is:",elem)val result = elem match {case i:Int => i + " is an int value"case d:Double => d + " is an double value"case "spark" => "spark is find"case s:String => s + " is a string value"case _ => "this is an unexpected value"}println(result)
    }
    
  6. 模式哨卫匹配(case 后面 + if 表达式,可不加括号)

    val response:String ="ok1"
    response match {case s if s!= null  => println(s"Received '$s'")case s => println("ERROR! Received a null response")
    }
    
  7. 模式变量匹配类型(应该不常用)

循环(表达式的控制结构)

  1. for 循环<-类似python 中的 in(x <- 1 to 7 by 1) 为生成器

    for (x <- 1 to 7 by 1) {println(s"Day $x")}
    println(s"${"*"*3}等价于${"*"*3}")
    val week = for (x <- 1 until 8 by 1) yield {s"Day $x:"} //返回值将作为一个集合返回,可迭代,for 推导式
    for (day <- week) print(day+",")    // print 不换行
    
  2. 迭代器哨卫(iterator guard/filter,增加一个 if表达式)
    val threes = for(i<-1 to 20 if i%3==0) yield i
    val quote = "Faith,Hope,,Charity,null"
    for {t<-quote.split(",");if t!=null;if t.size>0}{println(t)} //迭代器与迭代器哨卫 分开
    
  3. 嵌套迭代器(多层循环):scala> for {x<-1 to 2;y<-3 to 5}{print(s"($x,$y)")}
  4. 值绑定 for 循环:val powersOf2 = for (i<-0 to 8;pow=1<<i) yield pow // 1 左移 i 位
  5. while/do…while… 循环
    1. while:scala> var x=10;while (x>=0) x -= 1
    2. do…while:val x=0;do println(s"Here I am,x=$x") while (x>0)

第4章 函数

定义:def multiplier(x:Int,y:Int): Int = {x*y}
函数返回值:一般为表达式块最后一行,也可以使用 return 关键字返回并退出

  1. 过程 procedure:没有返回值的函数

    1. 隐式返回类型:def log(d:Double) = println(f"Got value $d%.2f")
    2. 显示返回类型:def log(d:Double):Unit = println(f"Got value $d%.2f")
  2. 无参函数:def hi():String ="hi"
  3. 块表达式函数:参数为块表达式,可赋 默认值
    def formatEuro(amt:Double = 10) = f" $amt%.2f"
    formatEuro{val rate = 0.011;1500*rate}
    
  4. 递归函数
    1. 递归缺点:栈溢出,调用递归函数太多,耗尽分配的内存
    2. 尾递归特点:不使用额外的栈空间
    // 计算 x^n 幂
    def powerN(x:Int,n:Int):Double = {n match {case n if n<0 => 1.0/x * powerN(x,n+1);case n if n>=1 => x * powerN(x,n-1);case n => 1}
    }// tail-recursion 递归调用函数本身作为返回值,才能由Scala 编译器完成尾递归优化
    @annotation.tailrec
    def power(x:Int,n:Int,t:Int=1):Int = {if (n<1) 1else power(x,n,x*t)
    }
    
  5. 嵌套函数
    def max(a:Int,b:Int,c:Int):Int = {def max(x:Int,y:Int) = if(x>y) x else ymax(a,max(b,c)) // 局部函数优先于外部函数
    }
    
  6. Vararg 参数
    def mysum(item:Int*):Int = {var total = 0for (i<- item) total += itotal
    }mysum();mysum(20,30)
    
  7. 参数组:def max(x:Int,y:Int) = if(x>y) x else y
  8. 方法和操作符
    1. 函数常存在于对象中,函数更适合的说法通常是方法
    2. Scala 没有任何四则运算符,Scala 使用的算术运算符其实都是实例的方法。这里不使用传统点记法,而是使用空格来分割对象(2)、操作符方法(+)、和方法的参数(3)。例如:2 + 3scala 的操作符记法为2.+(3)
    val d= 65.642
    d.compare(18.0)
    d compare 18.0
    1 + 2 + 3
    (1.+(2)).+(3)
    

第六章 常用数据类型

  1. List:可迭代

    1. filter:List(23,8) filter (_ > 18)
    2. 合并:List(List(1,2),List(3,4)).flatten
    3. 拆分:List(1,2,3,4,5) partition (_<3)
    4. 切片:List(1,2,3,4,5) slice (1,3)
    5. top n:List(1,2,3,4,5) take 3
    6. zip:List(1,2) zip List("a","b")
    val colors = List("red","green","blue")
    println(s"The colors value's size head remain is ${colors.size},${colors.head},${colors.tail}")
    colors(1) // List 下标从 0 开始// 高阶函数
    colors.foreach((c:String)=>println(c))
    val numbers = colors.map((c:String)=> c.size)\
    val total_str = colors.reduce((a:String,b:String)=> a+" "+b)
    
  2. Set

    var myset = Set("hadoop","spark") // myset 可以指向不同的地址。Set 默认不可变
    myset += "scala"    // myset 指向另一个不可变 地址import Scala.collection.mutable.Set // 可变集合
    val myset1 = Set("hadoop","spark")
    myset1 += "cloud computing" // myset1 指向地址不变,Set 内容增加
    
  3. Cons 操作符

  4. 映射(Map)

    val uni = Map("xmu"->"xiamen uin","thu"->"Tsinghua uin") // 默认不可变
    val xmu = if(uni.contains("xmu")) uni("xmu") else 0
    println(xmu)import scala.collection.mutable.Map
    val uni = Map("xmu"->"xiamen uin","thu"->"Tsinghua uin") // 可变
    uni("xmu") = "xiamen university" // update
    uni("fzu") = "fuzhou uni"
    uni += ("tju"->"tianjin uni")
    uni += ("tju"->"tianjin uni","whu"->"wuhan uni")for ((k,v) <- uni) printf("code is: %s and name is: %s\n",k,v)  // 遍历
    for (k <- uni.keys) println(k)
    for (k <- uni.values) println(v)
    
  5. 迭代器(Iterator):基本操作:next(),hasNext

    val iter = Iterator("hadoop","spark")
    while (iter.hasNext){println(iter.next())}
    for (ele <- iter) println(ele)
    
  6. else

基本语法

写入文件:Scala 需要java.io.PrintWriter 实现把数据写入文件

import java.io.PrintWriter
val out = new PrintWriter("/usr/local/output.txt")
for (i <- 0.8f to 1.6f by 0.2f) out.println(i)
out.close()

读取文件:可以使用 Scala.io.Source 的 getLines 方法 实现对文件中所有行读取

import scala.io.Source
val inputFile = Source.fromFile("output.txt")
val lines = inputFile.getLines
for (line <- lines) println(line)

异常处理:Scala 将所有异常都当作 不受检异常,使用 try-catch 结构捕获异常

// 暂不能运行
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOExceptiontry {val f = new FileReader("input.txt")
} catch {case ex:FileNotFoundException => println("file not found")case ex:IOException => println("IO error")case _ => println("else error")
}
finally{file.close()
}

class Counter{private var value = 0 // 外部不可访问def increment():Unit = {value += 1}def current():Int = value
}val mycounter = new Counter // 无参数可不加括号,下同
println(mycounter.current)
mycounter.increment
println(mycounter.current)
class Counter{var value = 0 // 外部可访问def increment(step:Int):Unit = {value += step} // 含参函数def current():Int = value
}
object Mycounter{def main(args:Array[String]){val mycounter = new Counter // 无参数可不加括号,下同println(mycounter.current)mycounter.increment(5)println(mycounter.current)}
}

getter 与 setter 方法

class Counter{private var privateValue = 0 // 外部可访问def value = privateValue    // 类似 Java 的 getter 方法def value_= (newValue:Int){// 类似 Java 的 setter 方法if (newValue > 0) privateValue = newValue}def increment(step:Int):Unit = {value += step} // 含参函数def current():Int = value
}
object Mycounter{def main(args:Array[String]){val mycounter = new Counterprintln(mycounter.value)mycounter.value = 3println(mycounter.value)mycounter.increment(5)println(mycounter.current)}
}

辅助构造器

  1. scala 构造器包含一个主构造器和若干个(>=0)辅助构造器
  2. 辅助构造器名称为 this,每个辅助构造器都必须调用已经定义辅助构造器或主构造器
class Counter{  // 类 主构造器private var value = 0   // 计数器起始值private var name = ""   // 计数器名称private var mode = 1    // 计数器类型def this(name:String){  // 第一个 辅助构造器,只能调用 主构造器this()  // 调用主构造器this.name = name}def this(name:String,mode:Int){this(name)this.mode = mode}def increment(step:Int):Unit = {value += step} // 含参函数def current():Int = valuedef info():Unit = {printf("Name:%s and mode is %d\n",name,mode)}
}
object Mycounter{def main(args:Array[String]){val mycounter1 = new Counter // 主构造器val mycounter2 = new Counter("Runner")val mycounter3 = new Counter("Timer",2)mycounter1.infomycounter1.increment(1)printf("current value is:%d\n",mycounter1.current)mycounter2.infomycounter2.increment(2)printf("current value is:%d\n",mycounter2.current)mycounter3.infomycounter3.increment(3)printf("current value is:%d\n",mycounter3.current)}
}class Counter(val name:String,val mode:Int){  // 类:主构造器private var value = 0   // 计数器起始值def increment(step:Int):Unit = {value += step} // 含参函数def current():Int = valuedef info():Unit = {printf("Name:%s and mode is %d\n",name,mode)}
}

单例对象 和 伴生对象

  1. 单例对象:对象定义不需要出现class,而是用 object。静态变量,每次调用都累加
  2. 伴生对象
    1. 同时包含实例方法 和 静态方法的类
    2. 当单例对象 与某类具有相同名称时,它被称为这个类的伴生对象
    3. 类及其伴生对象 必须存在于同一文件,可以相互访问
    4. 定义在伴生对象的方法都属于静态方法(static method)
class Person {private val id = Person.newPersonId() // 调用伴生对象(静态 static方法)private var name = ""def this(name:String){this()this.name = name}def info(){printf("The id of %s is %d.\n",name,id)}
}object Person { // 单例对象:类Person 的伴生对象private var lastId = 0private def newPersonId() = {lastId += 1lastId}def main(args:Array[String]){   // main 函数入口val person1 = new Person("ziyu")val person2 = new Person("minxing")person1.infoperson2.info}
}scalac hello.scala
scala -classpath . Person
javap Person // Java 反编译

继承

  1. 子类重写超类的抽象方法不需要使用 override 关键字
  2. 只有 主构造器 可以调用 超类中的 主构造器
  3. 可以重写超类中的字段
  4. 重写一个非抽象方法必须使用 override 修饰符
  5. Scala 和 Java 一样,不允许从多个超类中继承
  6. abstract 抽象类关键字,extends 继承关键字
abstract class Car{ // 抽象类:不能被直接实例化val carBrand :String    // 抽象字段:没初始化,必须声明类型def info()  // 抽象方法:没有定义任何方法的方法(空着)def greeting() {println("welcome to my car!")}  // 具体方法
}class BMWCar extends Car{override val carBrand = "BMW" // 重写超类字段,必须用 overridedef info(){printf("This is a %s car.It is on sale.\n",carBrand)} // 重写超类抽象方法, override 可忽略override def greeting(){println("welcome to my BMWCar car!")} // 重写超类具体方法, override 不可忽略
}object Mycar{def main(args:Array[String]){val mycar = new BMWCarmycar.greetingmycar.info}
}

特质(trait):继承多个父类

trait CarId{var id:Intdef currentId():Int
}
trait CarGreeting{def greeting(msg:String) {println(msg)}
}class BMWCarId extends CarId with CarGreeting{ // 可以使用多个 with 混入多个特质override var id:Int = 20000def currentId():Int = {id += 1;id} // 重写超类抽象方法, override 可忽略
}object Mycar{def main(args:Array[String]){val mycarid = new BMWCarIdmycarid.greeting("welcome my first car!")printf("my first carid is %d\n",mycarid.currentId)}
}

函数式编程

// 函数式编程实例 WordCount:对当前目录下文本文件进行词频统计
import java.io.File
import scala.io.Sourceobject WordCount{def main(args:Array[String]){val dirfile = new File("D:/documents/3_linzi_work/com_tools/bailing")val files = dirfile.listFilesfor (file <- files) println(file)val listFiles = files.toListval wordsMap = scala.collection.mutable.Map[String,Int]() // 声明可变映射listFiles.foreach(file=>Source.fromFile(file).getLines().foreach(line=>line.split(" ").foreach(word=> {if (wordsMap.contains(word)){wordsMap(word) += 1}else{wordsMap += (word->1)}})))println(wordsMap)for ((k,v)<- wordsMap) println(k+":"+v)}
}

Scala study相关推荐

  1. Scala的特质(Trait)介绍

    Scala的特质(Trait) 基本概念 特质声明 基本语法 特质的使用 基本语法 说明 案例实操 特质叠加 基本概念 案例实操 特质叠加执行顺序 案例说明 特质自身类型 说明 案例实操 特质和抽象类 ...

  2. 如何通过建造餐厅来了解Scala差异

    I understand that type variance is not fundamental to writing Scala code. It's been more or less a y ...

  3. Martin Odersky Scala编程公开课 第三周作业

    Functional Programming Principles in Scala  by Martin Odersky 这次的作业叫做Object-Oriented Sets.要完成一个完整的类, ...

  4. array函数参数 scala_3小时Scala入门

    〇,编程环境 1,安装Java 2,配置Java环境变量 3,安装Scala 4,配置Scala环境变量 参考文末阅读原文链接. 一,算术运算 二,输入输出 输出:println,print,prin ...

  5. Machine Learning Algorithms Study Notes--Supervised Learning

    转载自:http://www.tuicool.com/articles/VvuIvqU Machine Learning Algorithms Study Notes 高雪松 @雪松Cedro Mic ...

  6. Machine Learning Algorithms Study Notes

    2    Supervised Learning    3 2.1    Perceptron Learning Algorithm (PLA)    3 2.1.1    PLA -- " ...

  7. 第四课 尚硅谷Scala语言学习-面向对象

    第四课 尚硅谷Scala语言学习-面向对象 文章目录 第四课 尚硅谷Scala语言学习-面向对象 第一节 Scala 包 1.1 包基本语法 1.2 包说明 1.3 包对象 1.4 导包说明 第二节 ...

  8. spark学习02天-scala读取文件,词频统计

    1.在本地安装jdk环境和scala环境 2.读取本地文件: scala> import scala.io.Source import scala.io.Sourcescala> val ...

  9. Scala数组函数二(dropRight~intersect)

    dropRight 功能同drop,去掉尾部的n个元素 val a=Array(1,2,3,4,5) a.dropRight(2) Array[Int] = Array(1, 2, 3) dropWh ...

最新文章

  1. 10.15 iptables filter表案例
  2. 递归下降分析法(编译原理)
  3. python制作界面怎么触发事件_python模拟事件触发机制详解
  4. springboot 项目 测试环境在独立的tomcat部署
  5. C# 之 Win32 Api使用
  6. 好用的服务器终端,推荐7款超级好用的终端工具 —— SSH+FTP
  7. Java常量池详解:字符串常量池、Class常量池、运行时常量池 三者关系
  8. 总在说思科华为认证 可你真的清楚它们的区别吗?
  9. DefCamp CTF 2122 Rsa-factory 复现笔记
  10. 关于禁用Cookie的问题以及解决办法
  11. 关于QQ热键在不知道的情况下找出热键组合的办法
  12. 51系列、arduino、stm32系列驱动DAC模块TLC5615输出指定电压(可修改为波形输出)
  13. golang中os/signal包的使用
  14. [系统安全] 三十五.Procmon工具基本用法及文件进程、注册表查看
  15. 【华人学者风采】钱煦 加州大学圣地亚哥分校
  16. 新手小心:c语言的强符号和弱符号
  17. CentOS7 搭建Janus服务
  18. 调用命令强制关闭windows进程
  19. Linux篇19多线程第三部分
  20. IM开发——群组创建业务设计

热门文章

  1. Qt for iOS,Qt 与Objective C混合编程
  2. python判定固定时长固定频率的音频是否连续
  3. Python中亲和度分析时defaultdict的一种典型算法
  4. 2.阿里实人认证 .net 准备工作2 转换demo
  5. winrar正确破解方法
  6. 如何关闭 Intel RST
  7. 英语学(xiao 二声)习__字母读音
  8. 第三方支付企业风控体系简析——拉卡拉支付
  9. 待办日程用什么软件好 2022好用的便签记事日程管理软件推荐
  10. 驾考: 车内如何看左轮和右轮的位置 LTS