您现在的位置是:亿华云 > 域名
Scala,一门「特立独行」的语言!
亿华云2025-10-09 12:55:29【域名】1人已围观
简介本文转载自微信公众号「Piper蛋窝」,作者Piper蛋 。转载本文请联系Piper蛋窝公众号。入门 Spark 的路上很难不接触 Scala 。Scala 似乎是为 java 提供了很多『类似函数式
本文转载自微信公众号「Piper蛋窝」,特立作者Piper蛋 。独行的语转载本文请联系Piper蛋窝公众号。特立
入门 Spark 的独行的语路上很难不接触 Scala 。Scala 似乎是特立为 java 提供了很多『类似函数式编程』的语法糖,这里记录一下这个语言独特的独行的语地方分享给读者朋友们。
参考资料主要有:
曹洁 . Spark大数据分析技术(Scala版)[M]. 北京航空航天大学出版社,特立 2021. ISBN:9787512433854 陈欢 , 林世飞 . Spark最佳实践[M]. 人民邮电出版社, 2016. ISBN:9787115422286Scala 基本思想与注意事项
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 + 1 var one: Int = 1 var one: String = one // 函数 def addOne(x: Int): Int = x + 1 def 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的用法[1]
// 一.简单匹配,值匹配: 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=(.+)""".r val 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 90Scala 语法独特的地方
无参数方法,调用时不用加括号:args.isEmpty。
def width: Int = if (height == 0) 0 else contents(0).length width // 调用for 中使用 <- ,相当于 Python 的 in 。
继承用关键字 extends :class A(a: Int) extends B 。
单实例对象 / 静态成员变量与方法定义在 object 中:
object Timer { var count = 0 def currentCount() : Long = { count += 1 count } } 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 + n val 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:_* "Int") // _* 有种解包的意味使用 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、元组区别[2] Scala学习笔记5 (集合 Collections)[3]参考资料
[1]scala中case的用法: https://blog.csdn.net/qq_41669665/article/details/86158993
[2]scala中List、Array、ListBuffer、ArrayList、Set、元组区别: https://blog.csdn.net/mar_ljh/article/details/81910286
[3]Scala学习笔记5 (集合 Collections): https://blog.csdn.net/lyrebing/article/details/20362227
【责任编辑:武晓燕 TEL:(010)68476606】
很赞哦!(81154)
相关文章
- 在数以亿计的网站中,我们应该抓住每一个可能带来宣传的机会,域名可以带有企业的名字,一般可以使用汉语拼音或者英语单词或者是相关缩写的形式,只要用户记住了你企业的名字,就能很容易的打出你的网站域名,同样的,记住了网站域名也能很快的记住你公司的名字。
- 听说过CSS in JS,还有JS in CSS?
- 熬了三个晚上总结的Python 200个标准库!建议收藏
- Switch ... Case 语法你支不支持?
- 4、参加域名拍卖会
- 深入浅出ConcurrentHashMap内部实现
- Spring Boot定义接口的方法是否可以声明为private?
- 谈谈中台架构之交易中台
- 4.选择顶级的域名注册服务商
- JDK新特性-Lambda表达式的神操作