本博客采用創作共用版權協議, 要求署名、非商業用途和保持一致. 轉載本博客文章必須也遵循署名-非商業用途-保持一致的創作共用協議.
Scala簡介
Scala
是一門多范式的編程語言, 由Martin Odersky
于2001年基于Funnel的工作開始設計Scala并于2004年正式發布
- Scala是一種純面向對象的語言,每個值都是對象
- Scala是一門多范式編程語言, 支持命令交互式, 函數式, 面向對象
- 編譯型高性能語言(
靜態
) - 與Java無縫兼容, 可以使用任何Java庫
代碼風格
- 函數和變量以
小駝峰命名
- 類和特質以
大駝峰命名
- 常量使用全大寫命名
- 一般使用兩格縮進
- Scala大部分情況可以忽略語句末尾的分號
Scala變量
Scala中盡量避免使用變量, 函數式編程的一個重要特性是
不可變性
(不可變變量沒有副作用)
- Scala是靜態類型語言, 但是不需要顯式的指明變量類型, Scala采用類型推斷(
Type Inference
)
//定義一個變量
var x = 0
// 定義
val y = 1
Scala基本類型和操作
String和值類型Byte, Short, Int, Long, Float, Double, Char, Boolean
- Scala的操作符不是特殊的語言語法, 任何方法都可以是操作符
- 操作符分為前綴, 中綴, 后綴
- Scala中所有操作符都是方法調用
# 前綴
scala> (2.0).unary_-
res1: Double = -2.0
# 中綴
scala> x indexOf 'o'
res0: Int = 4
# 后綴
scala> val x = "Hello, World"
x: String = Hello, World
scala> x.toLowerCase
res0: String = hello, world
- 中綴操作符的兩個操作數, 一個在左一個在右
- 前綴操作符方法名在操作符上加了
unary_
前綴(+, -, !, ~
) - 后綴操作符是不用點或括號調用的不帶任何參數的方法
算術操作符: +, -, *, /, %
關系, 邏輯和位操作: >, <, >=, <=, ==, !=, &&, ||, &, |, ^, ~(反碼)
位移操作: <<, >>, >>>(無符號右移)
Scala函數
函數式語言的一個主要特征是, 函數是第一類結構
函數定義如下圖:
函數定義
-
Unit
的結果類型指的是函數沒有返回有用的值
函數式對象
object和class的區別在于: object關鍵字創建一個單例對象
- 主構造器是類的
唯一入口
, 只有主構造器可以調用超類構造器 -
override
關鍵字用于在重載父類的非抽象成員和成員函數 - 同一個類內函數名相同而參數類型和個數不同的函數重載不需要
override
class Rational (n: Int, d: Int) {
//precondition
require(d != 0)
// 私有成員
private val g = gcd(n.abs, d.abs)
var numer: Int = n / g
var denom: Int = d / g
// auxiliary constructor, 相當于python中__init__構造函數
def this(n: Int) = this(n, 1)
// 函數重載
override def toString = n + "/" + d;
def add(other: Rational): Rational =
new Rational(numer * other.denom + other.numer * denom, denom * other.denom)
def -(other: Rational): Rational =
new Rational(numer * other.denom - other.numer * denom, denom * other.denom)
// 函數重載
def -(i: Int): Rational =
new Rational(numer - i * denom, denom)
def *(other: Rational): Rational =
new Rational(numer * other.numer, denom * other.denom)
def lessThan(other: Rational): Boolean =
this.numer * other.denom < other.numer * this.denom
def max(other: Rational): Rational =
if (lessThan(other)) other else this
private def gcd(a: Int, b: Int): Int =
if (b == 0) a else gcd(b, a % b)
}
var x = new Rational(1, 3);
var y = new Rational(5, 7);
println(x add y)
println(x * y)
println(x - 1)
// 隱式轉換, 放在解釋器方位內
implicit def intToRational(x: Int) = new Rational(x)
println(1 - x)
繼承和多態
- 繼承
- 多態和動態綁定特性
動態綁定的特性即父類指針可以指向子類對象, 通過父類指針調用成員方法時, 會查找實際所指向的對象, 然后調用對象的內的對應方法
val el: Element = new ArrayElement(Array("hello"))
val e2: ArrayElement = new LineElement("hello")
內建控制結構
表示式會產生一個值
- Scala中if是能返回值的表達式, Scala中沒有三元操作符, 但通過
if (condition) var1 else var2
可以實現三元操作符的功能 - while和do-while被稱為
循環
, 不產生有意義的結果 - Scala中for語句非常強大,
for {子句} yield {循環體}
- match表達式可以產生值, match遠強大與其他語言中的
switch
, 而且不需要顯示的聲明break - 變量范圍: 大括號引入了一個新的范圍, 內部變量會遮蓋同名的外部變量
- 占位符語法
- 函數文本(匿名函數, 類似于python中的lamda)
var filename = if (!args.isEmpty) args(0) else "default.txt"
var filesList = (new File(".")).listFiles
// i <- 1 to 4(包含4), i <- 1 until 4 (不包含4)
for (file <- filesList
if file.isFile;
if file.getName.endsWith(".scala")) // 過濾器使用分號隔開
println(file)
var firstArg = if(args.length > 0) args(0) else ""
// 任何種類的常量和其他都可以作為case
firstArg match {
case "text" => println("text")
case _ => println("default")
}
// 匿名函數的寫法(lambda)
scala> var someNumbers = List(1, 2, 3, 4)
scala> someNumbers.filter(x => x % 2 == 0)
// 占位符語法
scala> someNumbers.filter(_ % 2 == 0)
// 偏函數 partial funciton
scala> def sum(a: Int, b: Int, c: Int) = a + b + c
scala> val a = sum(1, _: Int, 3)
scala> a(2)
// 變長參數(Array[String])
scala> def echo(args: String*) = for(arg <- args) println(arg)
scala> echo("one")
scala> echo("one", "two")
class DefaultConstructor ( name:String , age:Int){
def this(name:String){
/*自定義構造器,必需首先調用默認構造器*/
this(name , 24) ;
}
def show(){
println( name + "-->" + age ) ;
}
}
柯里化(carry)
// 普通函數
def sum(x: Int, y: Int) = x + y
// 柯里化函數
def sum(x: Int)(y: Int) = x + y
// 實際執行
def sum(x: Int) = (y: Int) => x + y
特質(trait)
特質就像帶有具體方法的java接口
特質和抽象類的區別: 抽象類主要用于有明確的父子繼承關系的類樹, 而特質可以用于任何類
特質定義使用trait
關鍵字
trait Person() {
def detail() {
println("I'm angry!")
}
}
// 使用extends或with混入特質, 從特質繼承的方法可以像從超類繼承的方法使用
class Student extends Person with Boy {
}
數據結構
- Python中常用
list, tuple, set, dict
- Scala對應的數據結構為
List, Tuple[X], Set, Map(HashMap)
- Scala中默認為不可變對象, 操作會生成一個新的對象
包
- Scala采用
java平臺的包機制
- 使用import來進行引用
package com.zhihu.antispam