Scala,一门「特立独行」的语言!
入门 Spark 的路上很难不接触 Scala 。 Scala 似乎是为 java 提供了很多『类似函数式编程』的语法糖,这里记录一下这个语言独特的地方分享给读者朋友们。
文章目录
- Scala 基本思想与注意事项
- 最基本的语法示例
- 类型的声明、控制结构(for、模式匹配、case)
- Scala 语法独特的地方
- Scala 的面向对象与一等公民“函数”
- 基本数据结构
- 注意事项与 Scala 奇技淫巧
- 关于数据结构的讨论(List or Array?)
参考资料主要有:
- 曹洁 . Spark大数据分析技术(Scala版)[M]. 北京航空航天大学出版社, 2021. ISBN:9787512433854
- 陈欢 , 林世飞 . Spark最佳实践[M]. 人民邮电出版社, 2016. ISBN:9787115422286
Scala 基本思想与注意事项
Sacla 即 Scalable Language ,正如其名,是一门可伸缩的编程语言:
- 基于 java 的虚拟机( Scala 会被编译成 JVM 字节码)
- 但是既可以当脚本使用,又可以构造大型系统
- 是静态语言,但是可以像动态语言那样支持交互式编程
- 面型对象:每一个值都是对象,每一次运算都是一次方法调用
- 函数式编程:所有函数都是对象,函数是“一等公民”
- Scala 中几乎一切都是表达式
scala
是解释器, scalac
是编译器;可以直接 scala test.scala
,也可以 scalac test.scala & scala test
(先把源码编译为字节码,再把字节码放到虚拟机中解释运行)。还可用输入 scala
进入交换编程界面。
所以要注意的是,需要先安装 JDK ,并且设置好环境变量 JAVA_HOME
。此外,更加重要的是, Scala 小版本兼容:2.12.x
与 2.13.x
这两者不兼容,2.12.10
与 2.12.11
才兼容。
最基本的语法示例
类型的声明、控制结构(for、模式匹配、case)
// 变量
val two: Int = 1 + 1var one: Int = 1
var one: String = 'one'// 函数
def addOne(x: Int): Int = x + 1def add(x: Int, y: Int): Int = {x + y
}// 部分控制结构
var filename = if (!args.isEmpty) args(0)else "default.txt"for (i <- 1 to 4)println("iteration " + i)
1 to 4
是 [1,2,3,4]
,而 i until 4
是 [1,2,3]
。
关于 for
还有一些奇技淫巧。
// 多个区间
for (a <- 1 to 2; b <- 1 to 2) {println("a: " + a + ", b: " + b)
}
// 结果
a: 1, b: 1
a: 1, b: 2
a: 2, b: 1
a: 2, b: 2// 过滤器
val list1 = List(3, 5, 2, 1, 7)
for (x <- list1 if x % 2 == 1) print(" " + x)
// 3 5 1 7
关于模式匹配,则有更多奇技淫巧。这里我直接参考:scala中case的用法
// 一.简单匹配,值匹配:val bools = List(true, false)
for (bool <- bools) {bool match {case true => println("heads")case false => println("tails")case _ => println("something other than heads or tails (yikes!)")}
}import scala.util.Random
val randomInt = new Random().nextInt(10)
randomInt match {case 7 => println("lucky seven!")case otherNumber => println("boo, got boring ol' " + otherNumber)
}// 二. 类型匹配val sundries = List(23, "Hello", 8.5, 'q')
for (sundry <- sundries) {sundry match {case i: Int => println("got an Integer: " + i)case s: String => println("got a String: " + s)case f: Double => println("got a Double: " + f)case other => println("got something else: " + other)
}
}// 三 根据顺序匹配val willWork = List(1, 3, 23, 90)
val willNotWork = List(4, 18, 52)
val empty = List()
for (l <- List(willWork, willNotWork, empty)) {l match {case List(_, 3, _, _) => println("Four elements, with the 2nd being '3'.")case List(_*) => println("Any other list with 0 or more elements.")}
}// 四 case里面用 guard 的数组匹配val tupA = ("Good", "Morning!")
val tupB = ("Guten", "Tag!")for (tup <- List(tupA, tupB)) {tup match {case (thingOne, thingTwo) if thingOne == "Good" =>println("A two-tuple starting with 'Good'.")case (thingOne, thingTwo) =>println("This has two things: " + thingOne + " and " + thingTwo)}
}// 五 对象深度匹配case class Person(name: String, age: Int)
val alice = new Person("Alice", 25)
val bob = new Person("Bob", 32)
val charlie = new Person("Charlie", 32)
for (person <- List(alice, bob, charlie)) {person match {case Person("Alice", 25) => println("Hi Alice!")case Person("Bob", 32) => println("Hi Bob!")case Person(name, age) =>println("Who are you, " + age + " year-old person named " + name + "?")}
}// 六 正则表达式匹配val BookExtractorRE = """Book: title=([^,]+),\s+authors=(.+)""".r
val MagazineExtractorRE = """Magazine: title=([^,]+),\s+issue=(.+)""".rval catalog = List("Book: title=Programming Scala, authors=Dean Wampler, Alex Payne","Magazine: title=The New Yorker, issue=January 2009","Book: title=War and Peace, authors=Leo Tolstoy","Magazine: title=The Atlantic, issue=February 2009","BadData: text=Who put this here??"
)for (item <- catalog) {item match {case BookExtractorRE(title, authors) =>println("Book \"" + title + "\", written by " + authors)case MagazineExtractorRE(title, issue) =>println("Magazine \"" + title + "\", issue " + issue)case entry => println("Unrecognized entry: " + entry)}
}
关于 case ,我想强调其在“解包”中的应用:
dict = Map("Piper" -> 95, "Bob" -> 90)
dict.foreach {case (k, v) => printf("grade of %s is %s/n", k, v)
}grade of Piper is 95
grade of Bob is 90
上述:使用了 foreach { case () => {} }
,注意 foreach
的大括号。与下面等效。
dict = Map("Piper" -> 95, "Bob" -> 90)
dict.foreach (x => println(s"grade of ${x._1} is ${x._2}")
)grade of Piper is 95
grade of Bob is 90
Scala 语法独特的地方
- 无参数方法,调用时不用加括号:
args.isEmpty
。
def width: Int = if (height == 0) 0 else contents(0).lengthwidth // 调用
for
中使用<-
,相当于 Python 的in
。继承用关键字
extends
:class A(a: Int) extends B
。单实例对象 / 静态成员变量与方法定义在
object
中:
object Timer {var count = 0def currentCount() : Long = {count += 1count}
}Timer.currentCount() // 直接调用class Timer {...
}
函数返回不必非要加
return
,默认最后一个表达式。函数式:匿名函数作为参数,并且还可以更简洁
val numbers = List(1, -3, -5, 9, 0)numbers.filter((x) => x > 0)
numbers.filter(x => x > 0)
numbers.filter(_ > 0) // 一个参数且函数中仅被使用一次时
_
具有特殊的意义与工作(占位)
// 部分应用函数
def adder(m: Int, n: Int) = m + nval add2 = adder(2, _: Int) // add2: (Int) => Int = <function1>
add2(3) // res1: Int = 5// 柯里化 currying
def curriedSum(x: Int)(y: Int) = x + y
curriedSum (1)(2)val onePlus = curriedSum(1)_ // 注意这里使用了 _
onePlus(2)// 模式匹配
var times = 1
times match {case 1 => "one"case 2 => "two"case _ => "other"
}
Scala 的面向对象与一等公民“函数”
(1).+(2) // 3
如上,(1)
是对象,.+(2)
是方法调用。 Scala 中万物皆对象。
var increase = (x: Int) => x + 1
如上,函数是一等公民,可以赋值给变量。
基本数据结构
有以下概念:
- 不可变列表
List
与可变列表ListBuffer
- 定长数组
Array
与变长数组ArrayBuffer
- 不可变集合
Set
与可变集合scala.collection.mutable.Set
- 映射
Map
与 可变映射scala.collection.mutable.Map
- 元组
Tuple
注意事项与 Scala 奇技淫巧
- 使用
until
是遍历数组的好办法,by
和_*
特殊意义:
for (i <- 0 until.length) { }Array (1,3,5,7,9,11) // 等价于
Array[Int](1 to 11 by 2:_*) // _* 有种解包的意味
- 使用
yield
生成数组
val a = Array(1, 2, 3, 4)
val res1 = for (ele <- a) yield 2 * ele
// 2, 4, 6, 8
- 元组的下标从
1
开始
val person = (1, 2, "ABC")
person._1 // 1
- 拉链操作
zip
val symbols = Array("<", "-", ">")
val counts = Array(2, 10, 2)
val pairs = symbols.zip(counts)
// Array[(String, Int)] = Array((<, 2), (-, 10), (>, 2))
for ((s, n) <- pairs) print(s * n)
<<---------->>
Map
神奇操作
// 创建
val dict = Map("Piper" -> 95, "Bob" -> 90)
val kv = Map(("Piper", 95), ("Bob", 90))// 取值
dict("Piper")// 合并 ++
dict ++ kv
dict.++(kv)// 添加 + ,删除 -
val n = dict + ("Tom" -> 91)
val l = dict - "Tom"
对于可变 Map
:
// += -=
dict += (("Tom", 91), ("Jerry", 87))
dict -= "Tom"
dict -= ("Jerry", "Bob")// ++= --= 与其他集合相联系
dict ++= List(("Tom", 91), ("Jerry", 87))
dict --= List("Jerry", "Bob")
::
与:::
创建列表
1::3::5::Nil // List[Int] = List(1, 3, 5)
注意 ::
是右结合的:(1::(3::(5::Nil)))
。
// ::: 用来连接列表
val L4 = L3 ::: List("Hadoop", "Hbase")
关于数据结构的讨论(List or Array?)
- 多用 List 而非 Array
- 列表的结构是递归的(即链表,
linkedList
),而数组是平等的
参考:
- scala中List、Array、ListBuffer、ArrayList、Set、元组区别
- Scala学习笔记5 (集合 Collections)
Scala,一门「特立独行」的语言!相关推荐
- c语言图形界面设定,「分享」C语言如何编写图形界面
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 贴吧内经常有人问C语言是不是只能用于字符终端界面开发,不能用于图形界面.大家也都有回答,需要其他的库.MFC,GTK,QT. 本人近期刚用GTK库加上纯C ...
- c语言界面怎么加图形,「分享」C语言如何编写图形界面
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 贴吧内经常有人问C语言是不是只能用于字符终端界面开发,不能用于图形界面.大家也都有回答,需要其他的库.MFC,GTK,QT. 本人近期刚用GTK库加上纯C ...
- C语言如何编写游戏界面,「分享」C语言如何编写图形界面
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 贴吧内经常有人问C语言是不是只能用于字符终端界面开发,不能用于图形界面.大家也都有回答,需要其他的库.MFC,GTK,QT. 本人近期刚用GTK库加上纯C ...
- C语言中图形方式界面怎么,「分享」C语言如何编写图形界面
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 贴吧内经常有人问C语言是不是只能用于字符终端界面开发,不能用于图形界面.大家也都有回答,需要其他的库.MFC,GTK,QT. 本人近期刚用GTK库加上纯C ...
- 能用c语言编写图形界面吗,「分享」C语言如何编写图形界面
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 贴吧内经常有人问C语言是不是只能用于字符终端界面开发,不能用于图形界面.大家也都有回答,需要其他的库.MFC,GTK,QT. 本人近期刚用GTK库加上纯C ...
- c语言可以编写图形界面吗,「分享」C语言如何编写图形界面
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 贴吧内经常有人问C语言是不是只能用于字符终端界面开发,不能用于图形界面.大家也都有回答,需要其他的库.MFC,GTK,QT. 本人近期刚用GTK库加上纯C ...
- c语言 显示 图形界面,「分享」C语言如何编写图形界面
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 贴吧内经常有人问C语言是不是只能用于字符终端界面开发,不能用于图形界面.大家也都有回答,需要其他的库.MFC,GTK,QT. 本人近期刚用GTK库加上纯C ...
- c语言怎么让图形界面单独显示,「分享」C语言如何编写图形界面
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 贴吧内经常有人问C语言是不是只能用于字符终端界面开发,不能用于图形界面.大家也都有回答,需要其他的库.MFC,GTK,QT. 本人近期刚用GTK库加上纯C ...
- 图形化c语言编程,「分享」C语言如何编写图形界面
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 贴吧内经常有人问C语言是不是只能用于字符终端界面开发,不能用于图形界面.大家也都有回答,需要其他的库.MFC,GTK,QT. 本人近期刚用GTK库加上纯C ...
最新文章
- Swift学习: 从Objective-C到Swift
- 一文讲懂图像处理中的低通、高通、带阻和带通滤波器
- 通过nginx配置文件抵御攻击,防御CC攻击的经典思路!
- mysql sycho_Java面试题 - osc_p1rj1z8j的个人空间 - OSCHINA - 中文开源技术交流社区
- python 随机取列表值 重复_python怎么随机取列表的值
- Some notes for CLFS2017
- C++中int id[sizeof(unsigned long)]的语句,正确吗?
- springboot处理参数再转发请求_SpringBoot是如何解析HTTP参数的
- 写存储过程与调用存储过程
- 修改web.config
- C语言实用算法系列之DOS传参“加减乘除计算器”
- Java Web文件下载
- Kali WiFi嗅探破解与字典生成
- Xen调度分析-RT
- U盘/移动硬盘 有写保护怎么解除【未解决】
- 软件经验|GDAL空间数据开源库开发介绍
- Excle 取前几位数、中间几位数、后几位数的方法
- 汉字转换为拼音Java工具类
- 英语--副词描述变化量大小
- Spring分析之IOC原理
热门文章
- Eclipse开发JSP页面,xhtml页面卡死的解决方法
- Spring @Autowired 调用别的包下的Bean 解决方法
- 解决sea.js引用jQuery提示$ is not a function的问题
- 最常见到的runtime exception 异常
- 检测到JSON.NET错误类型的自引用循环
- 您如何轻松地水平居中 div 使用CSS? [重复]
- 如何在正则表达式中使用变量?
- python 微服务 etcd_python etcd api
- L1-02 聪明的高斯 (5 分)
- 洛谷——P2637 第一次,第二次,成交