赞
踩
分布式高并发语言Go、R、Erlang等等为何选择Scala?
Spark是大数据处理的核心方式,用scala语言编写!
Kafka分布式发布订阅消息系统,由LinkedIn捐给Apache,以极高的吞吐量著称,是目前最火爆的MQ,用scala语言编写!
Flink最新一代分布式海量数据计算框架,Alibaba收购并开源,自己开发Blink分支,Scala语言编写!
为什么学习scala
1.基于强大的java基础。(.class文件)
2.大数据以及分布式的开发项目中(服务)都是基于java开发的
3.目前主流的大数据框架,比如:spark,kafka,Flink都是有scala语言写的
在我个人看来,Scala是一门非常优雅的语言,但优雅的背后要付出的辛苦也很多,比如学习Scala的人都会说,Scala语法非常简洁,但这也意味着抽象级别比较高,对初学者而言不好理解。也会有人说,Scala语法非常灵活,一个功能可以有非常多的实现方法,可以说条条大路通罗马,那么代价就是对于初学者来说,路多了反而不好选择。
所以在这里我对初学者的忠告是:在学习Scala前期,先走通一条路,屏蔽掉多余的干扰项,可能我们第一次使用Scala实现的项目看起来是非常笨拙的,但是没关系,任何的学习都是循序渐进的,不要追求一蹴而就。走通之后再回头,去寻找更好的替代方案。这样才能享受学习。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j8oo7WIx-1641901273021)(day09_scala.assets/20201014132327218.png)]
Scala combines object-oriented and functional programming in one concise, high-level language. Scala’s static types help avoid bugs in complex applications, and its JVM and JavaScript runtimes let you build high-performance systems with easy access to huge ecosystems of libraries.
Scala是一个将面向对象和函数式编程结合在一起的简洁的高级语言。Scala的静态类型有助于避免复杂应用程序中的错误,其可以运行在JVM和JavaScript的特点使您可以轻松访问庞大的生态系统库来构建高性能系统。
scala是一个语法简洁的面向对象的,函数式编程语言的特点,同时是一门强类型的语言。(多范式的编程语言)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8SJAhlW8-1641901273022)(day09_scala.assets/20201015104131762.png)]
Martin OrderSky马丁 奥德斯基 是JVM开发团队核心成员,是JDK1.5泛型,增强for循环,自动类型转换,JDK1.8Lambda等重要特性的作者.
在对JAVA的维护过程中,马丁非常推崇JAVA的面向对象及垃圾回收,是James Gosling的小迷弟. 但作为编辑器开发的狂热爱好者的他,又觉得JAVA的语法过于繁琐.所以相继自己开发了另外两种语言Pizza和Scala.其中Scala被用于实验室科研后推广开源.在上边提到JDK1.5和1.8的两个版本中的新特性就是从Pizza和Scala中迁移而来.
Scala诞生于2001年,但真正被人们所熟知并广泛应用于大数据开发是在十多年之后.可以说是Spark和Kafka带火了Scala.
James Gosling曾在采访中说,如果让他选择“今天使用的语言不是Java,那就是Scala”。
C:面向过程编程
Java:面向对象编程
Scala:面向函数编程
函数式编程:将所有复杂的问题的解决拆分为若干函数的处理,每一个函数可以去实现一部分功能,利用很多次函数的处理最终解决问题。函数式编程相对于面向对象编程更加的抽象,好处是代码可以非常的简洁,更多的采用常量而不是变量来解决问题,这样额外带来的好处是在线程并发时可以减少甚至杜绝多线程并发安全问题,特别适合于应用在处理高并发场景、分布式场景下的问题。函数式编程可以使用高阶函数,函数在scala中是一等公民,可以更加灵活的进行程序的编写。
函数式编程并不是面向对象编程的发展,而是另外一种解决问题的思路,两者之间也并没有绝对的好坏之分,在不同的场景中各有各的优缺点。
总结:Scala是一个面向对象的函数式编程语言.
java是由C语言开发,scala基于java,现在看来大部分情况下,青出于蓝而胜于蓝!
分布式开发中会面对很多棘手的问题,如面临服务器之间的通信、远程调用、序列化、反序列化等等。但有了scala这一切变得轻松,它全部都做了内部实现。让我们访问分布式集群环境就和访问单机一样简单。
同时Scala无缝集成Java,Scala编译器会先把源文件编译成.class文件再运行。Scala可以调用几乎所有的Java类库,也可以从Java应用程序中调用Scala的代码。它也可以访问现存的数之不尽的Java类库,这让用户(潜在地)迁移到Scala更加容易。
Java => 编译 => .class => JVM
Scala => 编译 => .class => JVM
Scala => JVM(支持,但不推荐,不是解释执行)
扩展:groovy、clojure(storm)都可以编译成.class,利用JVM。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rVuXV14M-1641901273022)(day09_scala.assets/20201014135229513.png)]
提示:Scala基于Java,需要提前安装JDK并配置环境变量
官网:https://www.scala-lang.org/
说明: 编写本篇教程时,Scala的最新版本为2.13.3,但是基于后续Spark\Kafka\Flink三个主流框架的版本及对Scala的版本要求.我们最终选择Scala-2.12.7这个版本作为基础环境. 2.11版本之后差别并不大,所以该文所有代码预计在2.11\2.12\2.13版本环境中都可以正常运行.
1.访问Scala官网,找到所需安装包进行下载.https://www.scala-lang.org/download/all.html
在这里,我们选择的是2.12.7这个版本进行下载.
2.进入2.12.7版本下载页后,在尾部找到对应系统安装包进行下载.
3.安装Scala,双击msi包,一路下一步即可.注意中间在安装目录选择时,路径不要有中文或空格.
选择合适的目录
4.检查环境
5.Hello World
在IDEA的File菜单中打开Settings窗口
选择Plugins在Marketplace中搜索Scala,找到Scala插件后点击Install.
等待插件下载完成,点击重启IEDA
创建一个新的工程
创建一个Object(至于什么是Object之后会详细解释)
命名为: cn.tedu.scalabasic.HelloWorld
选择Object选项
编写代码
package cn.tedu.scalabasic
/**
* 这是我们的第一个Scala程序!
*/
object HelloWorld {
def main(args: Array[String]): Unit = {
print("Hello World!!!")
}
}
右键运行
结果
主方法
Scala中注释的写法与Java一致
package cn.tedu.scalabasic /** * Scala基础语法 */ object ScalaGrammar { def main(args: Array[String]): Unit = { /* 1.注释 Scala中的注释形式与Java中一致.包括文档注释,多行注释,单行注释 */ /** * 这是一个文档注释 */ /* 这是一个多行注释 */ //这是一个单行注释 } }
在Scala代码中每行代码的结尾不需要分号";"作为结束符(自动推断),也可以加分号.
package cn.tedu.scalabasic /** * Scala基础语法 */ object ScalaGrammar { def main(args: Array[String]): Unit = { /* 2.代码分隔符 在Scala中,代码行与行之间的分隔符与Java相同,使用分号;,但是一般不需要写,Scala实现了自动推断. */ println("再见,貂蝉"); println("你好,西施") println("么么哒,上官婉儿") } }
在Scala中变量和常量分别使用var和val来定义.可以声明类型但不必要(类型自动推断).
其中,官方建议尽量不要使用var而是使用val来定义,有利于内存回收.和线程的安全.
package cn.tedu.scalabasic /** * Scala基础语法 */ object ScalaGrammar { def main(args: Array[String]): Unit = { /* 3.常量变量 在Scala中,变量使用var来定义,常量使用val定义 并且在定义变量和常量时一般都不写类型.Scala按照上下文可以自动推断 **重要**:在Scala中我们更推荐大家尽可能的使用常量来定义属性,这更利于内存回收. */ var a = 12 val b = 10 val c: Int = 11 a += 1 // b += 2 //编译报错,常量不可变 println(a) println(b) } }
Scala 可以使用两种形式的标志符,字符数字和符号。
字符数字使用字母或是下划线开头,后面可以接字母或是数字,符号" “ 在 S c a l a 中 也 看 作 为 字 母 。 然 而 以 ” “在 Scala 中也看作为字母。然而以” “在Scala中也看作为字母。然而以”“开头的标识符为保留的 Scala 编译器产生的标志符使用,应用程序应该避免使用”$"开始的标识符,以免造成冲突。
同时,Scala与Java相同的是同样建议使用驼峰规则命名.
package cn.tedu.scalabasic /** * Scala基础语法 */ object ScalaGrammar { def main(args: Array[String]): Unit = { /* 4.标识符 Scala标识符规则与Java大致相同.不能以符号和数字开头(_和$可以). 其中以$例外一般不作为标识符的开头使用,暂时不必深究. 命名格式推荐使用驼峰命名法:AaaBbb,aaaBbb,AAA_BBB 不能使用关键字和保留字命名 */ val userName = "张飞" // val if = 12 //编译报错,关键字和保留字不能用作标识符 } }
在Scala中有这样一句话:操作符即方法,方法即操作符
意思是方法可以按照操作符的使用规则来使用,操作符也可以按照方法的方式使用
package cn.tedu.scalabasic /** * Scala基础语法 */ object ScalaGrammar { def main(args: Array[String]): Unit = { /* 5.操作符和方法 在Scala中有这样一句话:操作符即方法,方法即操作符 意思是方法可以按照操作符的使用规则来使用,操作符也可以按照方法的方式使用 */ val str = "123_456_789" val strs = str split "_" //这里以操作符的形式(1 + 2)使用split方法 for (s <- strs) { println(s) } println(2.*(4)) //这里以方法的形式(a.split("_"))使用+操作符 //对于没有参数的方法,也可以不写括号 val num: Int = 123 println(num.toString()) println(num.toString) } }
在Java中,分为基本数据类型(8种) 和 引用类型(继承自Object).其中基本数据类型直接以字面量的形式赋值,没有属性和方法.
在Scala中数据类型与Java的设计类似,并且针对面向对象和函数式编程做了更进一步的优化.
其中:
Scala中有两种类型,AnyVal(值类型)和AnyRef(引用类型)都继承自Any(顶级父类).
AnyVal类型也是以"对象"形式存在,有属性和方法.声明时以字面量的形式声明.其中包含了类似Java中的8大基本类型:Byte\Short\Int\Long\Float\Double\Boolean\Char.除此之外还有一个特殊的Unit类型,表示空值(类似Java中的void).
AnyRef类型中包括所有的Scala内置对象和自定义的Scala对象,集合等,以及所有引用的Java对象.还定义了一个Null类型来表示空对象,他的默认值为null.
在Scala中还有一个非常特殊的Nothing类型.他是所有Scala类型的子类.被定义为abstract
值类型的定义
package cn.tedu.scalabasic import scala.collection.immutable.StringOps /** * AnyVal值类型的声明 */ object DataTypes { def main(args: Array[String]): Unit = { val a: Byte = 123 println(a,a.getClass) val b: Short = 123 println(b,b.getClass) val c: Int = 123 println(c,c.getClass) val d: Long = 123L //此处加不加L都可以 println(d,d.getClass) val e: Float = 1.23f //为区别Double,Float类型后加f println(e,e.getClass) val f: Double = 1.23 println(f,f.getClass) val g: Char = '@' println(g,g.getClass) val h: Boolean = false println(h,h.getClass) val i: Unit = "123" //不管这里赋值什么,他的值始终是()这是Unit的默认值. println(i,i.getClass) /* 特殊说明 虽然String是java.lang.String.在Scala中属于AnyRef类型, 但是在实际操作是会被隐式转换为StringOps类型属于AnyVal 通过以下实验可以证明 */ val j: String = "123" println(j,j.getClass) //(123,class java.lang.String) val k: StringOps = "123" println(k,k.getClass) //(123,class scala.collection.immutable.StringOps) } }
在Scala中类型的转换包括两种,一种是值类型转换,另外一种是引用类型转换,这里我们先重点讲解值类型的转换.
值类型可以通过以下方式进行转换:
范围大的数据类型通过 .toxxx 实现向范围小的数据类型强制转换,注意可能会造成精度的缺失.
package cn.tedu.scalabasic /** * 类型转换 */ object TypeTrans { def main(args: Array[String]): Unit = { /* 强制类型转换 范围大的数据类型通过 .toxxx 实现向范围小的数据类型强制转换,注意可能会造成精度的缺失. */ val h: Int = 12 val i: Double = 2.12 val j: Int = (h + i).toInt println(j) } }
package cn.tedu.scalabasic /** * 类型转换 */ object TypeTrans { def main(args: Array[String]): Unit = { /* 值类型和String类型之间的相互转换 */ //值类型转换为String类型有两种方式,分别是a+"" 和 a.toString val k:Int = 12 println(k+"",(k+"").getClass) val l:Int = 12 println(l.toString,(l.toString).getClass) //String类型数据转换为值类型的前提是可转,使用.toXxx val m:String = "123" // val m:String = "12·" //报错:java.lang.NumberFormatException println(m.toInt,m.toInt.getClass) } }
Scala中的算数运算符与Java基本一致,唯一不同是没有++和–-.
Scala中的赋值运算符与Java基本一致
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oyBwDFHo-1641901273024)(day09_scala.assets/1627610694772.png)]
Scala中的关系运算符与Java基本一致
Scala中的逻辑运算符与Java基本一致,但是在取反操作时不能像Java一样多层取反.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。