Scala入門教程詳解
Scala簡介
Scala(Scala Language的簡稱)語言是一種能夠運行于JVM和.Net平臺之上的通用編程語言,既可用于大規(guī)模應用程序開發(fā),也可用于腳本編程,它由由Martin Odersk于2001開發(fā),2004年開始程序運行在JVM與.Net平臺之上,由于其簡潔、優(yōu)雅、類型安全的編程模式而受到關(guān)注。
Scala語言具有如下特點:
1 純面向?qū)ο缶幊陶Z言
(1) Encapsulation/information hiding.
(2)Inheritance.
(3)Polymorphism/dynamic binding.
(4)All predefined types are objects.
(5) All operations are performed by sending messages to objects.
(6)All user-defined types are objects.
2 函數(shù)式編程語言
定義:Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data.
函數(shù)式編程語言應支持以下特性:
(1)高階函數(shù)(Higher-order functions)
(2)閉包( closures)
(3)模式匹配( Pattern matching)
(4)單一賦值( Single assignment )
(5)延遲計算( Lazy evaluation)
(6)類型推導( Type inference )
(7)尾部調(diào)用優(yōu)化( Tail call optimization)
(8)類型推導( Type inference )
3 Scala語言具有很強的兼容性、移植性
Scala運行于JVM上,能夠與JAVA進行互操作,具有與JAVA一樣的平臺移植性
Scala示例
/**
*
* scala是一門多范式編程語言,集成了面向?qū)ο缶幊毯秃瘮?shù)式編程等多種特性。
* scala運行在虛擬機上,并兼容現(xiàn)有的Java程序。
* Scala源代碼被編譯成java字節(jié)碼,所以運行在JVM上,并可以調(diào)用現(xiàn)有的Java類庫。
*/
/**
* 第一個Scala程序
* Scala和Java最大的區(qū)別是:Scala語句末尾的分號(;)是可選的!
* 編譯運行:
* 先編譯:scalac HelloScala.scala 將會生成兩個文件:HelloScala$.class和HelloScala.class
* 在運行:scala HelloScala
* 輸出結(jié)果:hello scala!!!
*
* object HelloScala{
def main(args: Array[String]): Unit = {
println("hello scala!!!")
}
}
*/
/**
* Scala基本語法:
* 區(qū)分大小寫
* 類名首字母大寫(MyFirstScalaClass)
* 方法名稱第一個字母小寫(myMethodName())
* 程序文件名應該與對象名稱完全匹配
* def main(args:Array[String]):scala程序從main方法開始處理,程序的入口。
*
* Scala注釋:分為多行/**/和單行//
*
* 換行符:Scala是面向行的語言,語句可以用分號(;)結(jié)束或換行符(println())
*
* 定義包有兩種方法:
* 1、package com.ahu
* class HelloScala
* 2、package com.ahu{
* class HelloScala
* }
*
* 引用:import java.awt.Color
* 如果想要引入包中的幾個成員,可以用selector(選取器):
* import java.awt.{Color,Font}
* // 重命名成員
* import java.util.{HashMap => JavaHashMap}
* // 隱藏成員 默認情況下,Scala 總會引入 java.lang._ 、 scala._ 和 Predef._,所以在使用時都是省去scala.的
* import java.util.{HashMap => _, _} //引入了util包所有成員,但HashMap被隱藏了
*/
/**
* Scala數(shù)據(jù)類型:
* Scala與Java有著相同的數(shù)據(jù)類型,下面列出一些Scala有的數(shù)據(jù)類型。
* Unit:表示無值,和其他語言的void一樣。
* Null:null或空引用。
* Nothing:是Scala的類層級的最低端,是任何其他類型的子類型。
* Any:是所有其他類的超類。
* AnyRef:是Scala所有引用類的基類。
*
* 多行字符串的表示方法:
val foo ="""第一行
第二行
第三行"""
*/
/**
* Scala變量:
* 在Scala中,使用關(guān)鍵字“var”聲明變量,使用關(guān)鍵字“val”聲明常量。
* var myVar1 : String = "foo"
* var myVar2 : Int
* val myVal = "Hello,Scala!"
* Scala多個變量聲明:
* val xmax, ymax = 100 // xmax,ymax都聲明為100
*/
/**
* Scala訪問修飾符:
* Scala訪問修飾符和Java基本一樣,分別有private、protected、public。
* 默認情況下,Scala對象的訪問級別是public。
*
* 私有成員:用private關(guān)鍵字修飾的成員僅在包含了成員定義的類或?qū)ο髢?nèi)部可見。
* class Outer{
* class Inner{
* private def f(){println("f")}
* class InnerMost{
* f() // 正確
* }
* (new Inner).f() // 錯誤
* }
* }
*
* 保護成員:Scala比Java中更嚴格。只允許保護成員在定義了該成員的類的子類中被訪問。
* package p{
* class Super{
* protected def f() {println("f")}
* }
* class Sub extends Super{
* f()
* }
* class Other{
* (new Super).f() // 錯誤
* }
* }
*
* 公共成員:默認public,這樣的成員在任何地方都可以被訪問。
* class Outer{
* class Inner{
* def f(){println("f")}
* class InnerMost{
* f() // 正確
* }
* }
* (new Inner).f() // 正確
* }
*
* 作用域保護:Scala中,訪問修飾符可以通過使用限定詞強調(diào)。
* private[x] 或者 protected[x]
* private[x]:這個成員除了對[...]中的類或[...]中的包中的類及他們的伴生對象可見外,對其他的類都是private。
*/
/**
* Scala運算符:和Java一樣,這里就不再浪費時間一一介紹了。
* 算術(shù)運算符、關(guān)系運算符、邏輯運算符、位運算符、賦值運算符。
*/
/**
* Scala if...else語句:和Java一樣,簡單列舉一下四種情況。
* if(...){
*
* }
*
* if(...){
*
* }else{
*
* }
*
* if(...){
*
* }else if(...){
*
* }else{
*
* }
*
* if(...){
* if(...){
*
* }
* }
*/
/**
* Scala循環(huán):和Java一樣,這里不贅述,只介紹三種循環(huán)類型。
* while循環(huán)、do...while循環(huán)、for循環(huán)
*/
/**
* Scala函數(shù):用一個例子來說明函數(shù)的定義和函數(shù)調(diào)用。
* object Test{
* def main(args: Array[String]){
* println(addInt(1,3)); // 函數(shù)調(diào)用
* }
* def addInt(a:Int, b:Int) : Int = { // 函數(shù)定義
* var sum:Int = 0
* sum = a + b
* return sum
* }
* }
*/
/**
* Scala閉包:
* 閉包是一個函數(shù),返回值依賴于聲明在函數(shù)外部的一個或多個變量。
* 例子:
* object Test{
* def main(args: Array[String]){
* println("muliplier(1) value = " + muliplier(1))
* println("muliplier(2) value = " + muliplier(2))
* }
* var factor = 3 // 定義在函數(shù)外的自由變量
* val muliplier = (i:Int) => i * factor // muliplier函數(shù)變量就是一個閉包
* }
* 輸出結(jié)果:
* muliplier(1) value = 3
* muliplier(2) value = 6
*/
/**
* Scala字符串:
*
* Scala中可以創(chuàng)建兩中字符串:一種是不可修改的,一種是可以修改的。
* // 創(chuàng)建不可修改的字符串
* val greeting:String = "Hello World!";
* // 創(chuàng)建可以修改的字符串
* object Test{
* def main(args: Array[String]){
* val buf = new StringBuilder;
* buf += 'a' // 添加一個字符
* buf ++= "bcdef" // 添加一個字符串
* println(buf.toString); // 輸出:abcdef
* }
* }
*
* 字符串長度:xxx.length()
*
* 字符串連接:可以用concat()方法或者用加號
* object Test {
def main(args: Array[String]) {
var str1 = "字符串1:";
var str2 = "字符串2";
var str3 = "字符串3:";
var str4 = "字符串4";
println( str1 + str2 ); // 字符串1:字符串2
println( str3.concat(str4) ); // 字符串3:字符串4
}
}
*
* 創(chuàng)建格式化字符串:
* String類中可以使用printf()方法來格式化字符串并輸出。
* object Test{
* def main(args:Array[String]){
* var floatVar = 12.456
* var intVar = 2000
* var stringVar = "字符串變量"
* var fs = printf("浮點型變量為 " +
* "%f,整形變量為 %d, 字符串為 " +
* "%s", floatVar, intVar, stringVar)
* println(fs) // 浮點型變量為 12.456000, 整型變量為 2000, 字符串為 字符串變量
* }
* }
*/
/**
* Scala數(shù)組:
* 1、聲明數(shù)組
* var z:Array[String] = new Array[String](3) 或者 var z = new Array[String]()
* z(0) = "value1"; z(1) = "value2"; z(2) = "value3"
*
* var z = Array("value1", "value2", "value3")
*
* 2、處理數(shù)組
* object Test{
* def main(args: Array[String]){
* var myList = Array(1.1, 2.2, 3.3, 4.4)
*
* // 輸出所有數(shù)組元素
* for(x <- myList){
* println(x)
* }
*
* // 計算數(shù)組所有元素的總和
* var total = 0.0
* for(i <- 0 to (myList.length - 1)){
* total += myList(i)
* }
* println("總和:" + total)
*
* // 查找數(shù)組中的最大元素
* var max = myList(0)
* for(i <- 1 to (myList.length - 1)){
* if(myList(i) > max)
* max = myList(i)
* }
* println("最大值:" + max)
* }
* }
*
* 3、多維數(shù)組
* import Array._
* object Test{
* def main(args: Array[String]){
* // 定義數(shù)組
* var myMatrix = ofDim[Int](3,3)
* // 創(chuàng)建矩陣
* for(i <- 0 to 2){
* for(j <- 0 to 2){
* myMatrix(i)(j) = j;
* }
* }
* // 打印矩陣
* for(i <- 0 to 2){
* for(j <- 0 to 2){
* print(" " + myMatrix(i)(j));
* }
* println();
* }
* }
* }
*
* 4、合并數(shù)組
* import Array._
* object Test{
* def main(args: Array[String]){
* var myList1 = Array(1.1, 2.2, 3.3, 4.4)
* var myList2 = Array(5.5, 6.6, 7.7, 8.8)
* // 使用concat()合并
* var myList3 = concat(myList1, myList2)
* // 輸出所有數(shù)組元素
* for(x <- myList3){
* println(x)
* }
* }
* }
*
* 5、創(chuàng)建區(qū)間數(shù)組:使用range(x,y,z)創(chuàng)建區(qū)間數(shù)組,數(shù)值范圍大于等于x,小于y。z表示步長,默認為1。
* object Test{
* def main(args: Array[String]){
* var myList1 = range(10, 20, 2)
* var myList2 = range(10, 20)
* for(x <- myList1){
* print(" " + x) //輸出:10 12 14 16 18
* }
* println()
* for(x <- myList2){
* print(" " + x) // 輸出:10 11 12 13 14 15 16 17 18 19
* }
* }
* }
*/
/**
* Scala集合:分為可變集合和不可變集合。
* 可變集合:可以在適當?shù)牡胤奖桓禄驍U展,也就是可以修改、添加、移除一個集合的元素。
* 不可變集合:永遠不會改變。但可以模擬添加、移除、更新操作,但是這些操作將在每一種情況下都返回一個新的集合,
* 同時使原來的集合不發(fā)生改變。
* // 定義整形List
* val x = List(1,2,3,4)
* // 定義Set
* var x = Set(1,3,5,7)
* // 定義Map
* val x = Map("one" -> 1, "two" -> 2, "three" -> 3)
* // 創(chuàng)建兩個不同類型的元組
* val x = (10, "Runoob")
* // 定義Option
* val x:Option[Int] = Some(5)
*/
/**
* Scala迭代器:
* 迭代器不是一個集合,而是一個用于訪問集合的方法。
*
*/
/*object Test{
def main(args: Array[String]): Unit = {
val it = Iterator("one", "two", "three", "four")
while(it.hasNext){ // 檢測集合中是否還有元素
println(it.next()) // 返回迭代器的下一個元素,并更新迭代器的狀態(tài)
}
val ita = Iterator(1, 2, 3, 4, 5)
val itb = Iterator(11, 22, 33, 44, 55)
//println(ita.max) // 查找最大元素
//println(itb.min) // 查找最小元素
println(ita.size) // 獲取迭代器的長度
println(itb.length) // 獲取迭代器的長度
}
}*/
/**
* Scala類和對象:
* 類是對象的抽象,對象是類的具體實例。
* 類是抽象的,不占用內(nèi)存;對象是類的具體實例,占用存儲空間。
*
*/
/*import java.io._
class Point(xc: Int, yc: Int){
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int): Unit ={
x = x + dx
y = y + dy
println("x點的坐標是:" + x)
println("y點的坐標是:" + y)
}
}
object Test{
def main(args: Array[String]): Unit = {
val pt = new Point(10, 20)
// 移到一個新的位置
pt.move(10, 10)
}
}*/
/**
* Scala繼承:跟Java差不多。
* 1、重寫一個非抽象方法必須使用override修飾符
* 2、只有主構(gòu)造函數(shù)才可以往基類的構(gòu)造函數(shù)里寫參數(shù)
* 3、在子類中重寫超類的抽象方法時,不需要使用override
*/
/*class Point(val xc: Int, val yc: Int){
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int): Unit ={
x = x + dx
y = y + dy
println("x點的坐標是:" + x)
println("y點的坐標是:" + y)
}
//-------------------------------------
var name = ""
override def toString = getClass.getName + "[name=" + name + "]"
}
class Location(override val xc: Int, override val yc: Int,
val zc: Int) extends Point(xc, yc){ // 繼承 重寫了父類的字段
var z: Int = zc
def move(dx: Int, dy: Int, dz: Int){
x = x + dx
y = y + dy
z = z + dz
println("x點的坐標是:" + x)
println("y點的坐標是:" + y)
println("z點的坐標是:" + z)
}
//---------------------------------------
var salary = 0.0
override def toString = super.toString + "[salary=" + salary + "]"
}
object Test{
def main(args: Array[String]): Unit = {
val loc = new Location(10, 20, 30)
loc.move(10, 10 ,5)
//------------------------------------
loc.name = "lc"
loc.salary = 35000.0
println(loc)
}
}*/
/**
* Scala單例對象:
* Scala中沒有static,要使用object關(guān)鍵字實現(xiàn)單例模式。
* Scala中使用單例模式時,除了定義類,還要定義一個同名的object對象,它和類的區(qū)別是,object對象不能帶參數(shù)。
* 當單例對象與某個類共享一個名稱時,他被稱作這個類的伴生對象。
* 必須在同一個源文件里定義類和它的伴生對象。
* 類和它的伴生對象可以互相訪問其私有成員。
*/
/*// 私有構(gòu)造方法
class Marker private(val color:String) {
println("創(chuàng)建" + this)
override def toString(): String = "顏色標記:"+ color //4:顏色標記:red
}
// 伴生對象,與類共享名字,可以訪問類的私有屬性和方法
object Marker{
private val markers: Map[String, Marker] = Map(
"red" -> new Marker("red"), //1:創(chuàng)建顏色標記:red
"blue" -> new Marker("blue"), //2:創(chuàng)建顏色標記:blue
"green" -> new Marker("green") //3:創(chuàng)建顏色標記:green
)
def apply(color:String) = {
if(markers.contains(color)) markers(color) else null
}
def getMarker(color:String) = {
if(markers.contains(color)) markers(color) else null //5:顏色標記:blue
}
def main(args: Array[String]) {
println(Marker("red"))
// 單例函數(shù)調(diào)用,省略了.(點)符號
println(Marker getMarker "blue")
}
}*/
/**
* Scala Trait(特征):
* 相當于Java的接口,但比接口功能強大,它還可以定義屬性和方法的實現(xiàn)。
* 一般情況下Scala的類只能單繼承,但特征可以實現(xiàn)多重繼承。
*/
/*// 定義特征
trait Equal{
def isEqual(x: Any): Boolean // 未實現(xiàn)的方法
def isNotEqual(x: Any): Boolean = !isEqual(x) // 實現(xiàn)了的方法
}
class Point(xc: Int, yc: Int) extends Equal{
var x: Int = xc
var y: Int = yc
override def isEqual(obj: Any): Boolean =
obj.isInstanceOf[Point] &&
obj.asInstanceOf[Point].x == x
}
object Test{
def main(args: Array[String]): Unit = {
val p1 = new Point(2, 3)
val p2 = new Point(2, 4)
val p3 = new Point(3, 3)
println(p1.isNotEqual(p2))
println(p1.isNotEqual(p3))
println(p1.isNotEqual(2))
}
}*/
/**
* 特征構(gòu)造順序:
* 構(gòu)造器的執(zhí)行順序:
* 1、調(diào)用超類的構(gòu)造器
* 2、特征構(gòu)造器在超類構(gòu)造器之后、類構(gòu)造器之前執(zhí)行
* 3、特征由左到右被構(gòu)造
* 4、每個特征當中,父特征先被構(gòu)造
* 5、如果多個特征共有一個父特征,父特征不會被重復構(gòu)造
* 6、所有特征被構(gòu)造完畢,子類被構(gòu)造
*/
/**
* Scala模式匹配:
* 選擇器 match {備選項}
*/
/*object Test{
def main(args: Array[String]): Unit = {
println(matchTest("two"))
println(matchTest("test"))
println(matchTest(1))
println(matchTest(6))
}
def matchTest(x: Any): Any = x match {
case 1 => "one"
case "two" => 2
case y: Int => "scala.Int" // 對應類型匹配
case _ => "many" // 默認全匹配選項
}
}*/
/**
* 使用樣例類:
* 使用case關(guān)鍵字的類定義就是樣例類,樣例類是種特殊的類,經(jīng)過優(yōu)化以用于模式匹配。
*/
/*object Test{
def main(args: Array[String]): Unit = {
val alice = new Person("Alice", 25)
val bob = new Person("Bob", 32)
val charlie = new Person("Charlie", 27)
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("Age: " + age + " year,name: " + name +"?")
}
}
}
// 樣例類
case class Person(name: String, age: Int)
}*/
/**
* Scala正則表達式:
* 和Java差不多,在用的時候查一下就行了。
*/
/**
* Scala異常處理:
* 和Java類似。在Scala中借用了模式匹配的方法來在catch語句塊中來進行異常匹配。
*/
/*import java.io.{FileNotFoundException, FileReader, IOException}
object Test{
def main(args: Array[String]): Unit = {
try {
val f = new FileReader("input.txt")
}catch {
case ex: FileNotFoundException => {
println("Missing file exception")
}
case ex: IOException => {
println("IO Exception")
}
}finally {
println("Exiting finally...")
}
}
}*/
/**
* Scala提取器(Extractor):
* apply方法:無需new操作就可創(chuàng)建對象。
* unapply方法:是apply方法的反向操作,接受一個對象,然后從對象中提取值,提取的值通常是用來構(gòu)造對象的值。
*/
/*object Test {
def main(args: Array[String]) {
println ("Apply 方法 : " + apply("Zara", "gmail.com")); // 也可直接Test("Zara", "gmail.com")來創(chuàng)建Zara@gmail.com
println ("Unapply 方法 : " + unapply("Zara@gmail.com"));
println ("Unapply 方法 : " + unapply("Zara Ali"));
}
// 注入方法 (可選)
def apply(user: String, domain: String) = {
user +"@"+ domain
}
// 提取方法(必選)
def unapply(str: String): Option[(String, String)] = {
val parts = str split "@"
if (parts.length == 2){
Some(parts(0), parts(1))
}else{
None
}
}
}*/
/**
* 提取器使用模式匹配:
* 在我們實例化一個類的時,可以帶上0個或者多個的參數(shù),編譯器在實例化的時會調(diào)用 apply 方法。
*/
/*object Test {
def main(args: Array[String]) {
val x = Test(5)
println(x)
x match
{
case Test(num) => println(x + " 是 " + num + " 的兩倍!") //2:10是5的兩倍!
//unapply 被調(diào)用
case _ => println("無法計算")
}
}
def apply(x: Int) = x*2 //1:10
def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None
}*/
/**
* Scala文件I/O:
*
*/
/*// 文件寫操作
import java.io._
object Test {
def main(args: Array[String]) {
val writer = new PrintWriter(new File("test.txt" ))
writer.write("Scala語言")
writer.close()
}
}*/
// 從屏幕上讀取用戶輸入
/*object Test {
def main(args: Array[String]) {
print("請輸入菜鳥教程官網(wǎng) : " )
val line = Console.readLine // 在控制臺手動輸入
println("謝謝,你輸入的是: " + line)
}
}*/
// 從文件上讀取內(nèi)容
/*import scala.io.Source
object Test {
def main(args: Array[String]) {
println("文件內(nèi)容為:" )
Source.fromFile("test.txt" ).foreach{
print
}
}
}*/
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot 項目中的圖片處理策略之本地存儲與路徑映射
在SpringBoot項目中,靜態(tài)資源存放在static目錄下,使得前端可以通過URL來訪問這些資源,我們就需要將文件系統(tǒng)的文件路徑與URL建立一個映射關(guān)系,把文件系統(tǒng)中的文件當成我們的靜態(tài)資源即可,本文給大家介紹SpringBoot本地存儲與路徑映射的相關(guān)知識,感興趣的朋友一起看看吧2023-12-12
mybatis-plus查詢無數(shù)據(jù)問題及解決
這篇文章主要介紹了mybatis-plus查詢無數(shù)據(jù)問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
Spring boot 數(shù)據(jù)源未配置異常的解決
這篇文章主要介紹了Spring boot 數(shù)據(jù)源未配置異常的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
springboot 運行 jar 包讀取外部配置文件的問題
這篇文章主要介紹了springboot 運行 jar 包讀取外部配置文件,本文主要描述linux系統(tǒng)執(zhí)行jar包讀取jar包同級目錄的外部配置文件,主要分為兩種方法,每種方法通過實例代碼介紹的非常詳細,需要的朋友可以參考下2021-07-07
spring boot udp或者tcp接收數(shù)據(jù)的實例詳解
這篇文章主要介紹了spring boot udp或者tcp接收數(shù)據(jù),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-12-12

