Scala
一些简单的小概述
用于练习以及开发的 Scala 版本:2.11.8
这里使用 IDEA 作为 Scala 的 IDE
注意,我们必须安装 scala 插件 才可以创建scala项目
一个简单的字符串替换 demo:
object Main {
def main(args: Array[String]): Unit = {
var s1 = "Cecilia"
println(s"Hello ${s1}")
}
}
// Hello Cecilia
注意,scala 2.11 必须配合 JDK1.8 进行编译
Scala 是一种存在类型推断的语言
Scala 可以将函数作为变量进行赋值:
var f = ()
此时,f 是一个没有返回值的函数,数据类型会被定义为 Unit
var f = {1}
此时 f 是一个只有返回值为 1 的函数
数据类型也可以是 Nothing,这代表函数返回了一个 Exception,就像下面这样:
def myFunction = throw new Exception("Error")
变量、函数、条件、循环
var 定义变量、val 定义常量
在Scala中,函数的最后一句话就是其返回值,if…else…也是具有返回值的,其返回值就是其最后的内容:
def myFunction(x:Int):Int = {
if (x < 1)
1
else
x * myFunction(x - 1)
}
一个简单的循环列表的示例:
var list = List("Tom", "Mary", "Lily")
for (item <- list) {
println(item)
}
在循环中进行判断:
var list = List("Tom", "Mary", "Lily")
// 若长度大于 3 ,则进入循环
for (item <- list if (item.length > 3)) {
println(item)
}
yield关键字
yield 关键字用于产生一个新的集合。
示例:
// 生成一个新的集合,这种的话就只能使用 单蹦一个 for 关键字的写法
val newList = for {
item <- list
itemNewList = item.toUpperCase
} yield(itemNewList)
另外还有更快的方式;
list.foreach(println)
函数中的 call by value 和 call by name
call by value 指的是咱函数的参数传递过程中,传入实参时直接将实参计算出结果
call by name 指的是在函数参数传递过程中,在调用到该实参的时候才进行计算
特别的例子:
object Main {
def main(args: Array[String]): Unit = {
println(bar(1, loop())) // 1,因为没有用到第二个形参
println(bar(loop(), 1)) // 死循环
}
def bar(x: Int, y: => Int): Int = {
1
}
def loop(): Int = {
loop()
}
}
函数的参数传递
设置默认值,指定对应参数以及可变参数:
object Main {
def main(args: Array[String]): Unit = {
println(myFunc("Cecilia"))
}
def myFunc(name: String = "Jack") = "Hello, " + name
}
在函数传递时设置传递的变量方向:
object Main {
def main(args: Array[String]): Unit = {
println(myFunc("Cecilia"))
println(myFunc2(age = 18))
println(myFunc3(1, 2, 3, 4, 5, 6, 7, 8, 9))
}
def myFunc(name: String = "Jack") = "Hello, " + name
def myFunc2(name: String = "Cecilia", age: Int = 25) = {
"Hello " + name + ", Today is your " + age + "th birthday!"
}
def myFunc3(age: Int*) = {
var result = 0
for (i <- age ) {
result += i
}
result
}
}
其他特性
懒加载
使用 lazy 标注 val 的变量定义可以令某些操作延时加载,这在 spark 的操作中十分有用
val words = scala.io.Source.fromFile("test.txt").mkString
println(words)
lazy val words2 = scala.io.Source.fromFile("test.txt").mkString
println(words2)
异常补获
try{
val words = scala.io.Source.fromFile("te0st.txt").mkString
println(words)
}catch{
case ex1: java.io.FileNotFoundException => {
println("没有这个文件")
}
case ex2: IllegalArgumentException => {
println("参数非法")
}
case _: Exception => {
println("发生其余异常")
}
}
scala 中的数组
import scala.collection.mutable.ArrayBuffer
object Main {
def main(args: Array[String]): Unit = {
// 定长数组
val aList = new Array[Int](3)
val bList = Array[Int](3)
val cList = Array[String]("a", "b", "c")
// 可变长数组
val d = new ArrayBuffer[String]()
d += "Hello"
d += "World"
d.toArray // 转为定长数组
d.foreach(println) // 遍历数组,相当于传入一个函数,令数组中的每个元素作为实参传入这个函数
// 降序排序
d.sortWith((a, b) => {
if (a > b) {
true
}else {
false
}
})
}
}
元组与映射
映射(Map)
import scala.collection.mutable.ArrayBuffer
object Main {
def main(args: Array[String]): Unit = {
// 定长映射
val source = Map("Mike" -> 30, "Mary" -> 35, "Lily" -> 24)
// 可变长映射
val chinese = scala.collection.mutable.Map("Mike" -> 30, "Mary" -> 35, "Lily" -> 24)
// 或者这样创建
val chinese1 = scala.collection.mutable.Map(("Tom", 30), ("Jerry", 40), ("Trump", 80))
// 这样取
chinese("Trump")
// 避免取不到的情况
if (chinese.contains("Trump")) {
chinese("Trump")
}
// 这种情况也可以简写:
chinese.getOrElse("Trump", -1) // 若不存在则返回 -1
}
}
元组
元组就是存储一组可以存储不同类型数据的集合:
def main(args: Array[String]): Unit = {
// 注意这里的数字代表代表Tuple的长度
val t = new Tuple4("Mike", 3.147, 999999, "HelloWorld")
// 元组的遍历比较特殊,需要使用迭代器
t.productIterator.foreach(println)
}