Scala入門筆記

本博客采用創作共用版權協議, 要求署名、非商業用途和保持一致. 轉載本博客文章必須也遵循署名-非商業用途-保持一致的創作共用協議.

Scala簡介

Scala 是一門多范式的編程語言, 由Martin Odersky 于2001年基于Funnel的工作開始設計Scala并于2004年正式發布

  • Scala是一種純面向對象的語言,每個值都是對象
  • Scala是一門多范式編程語言, 支持命令交互式, 函數式, 面向對象
  • 編譯型高性能語言(靜態)
  • 與Java無縫兼容, 可以使用任何Java庫

代碼風格

  1. 函數和變量以小駝峰命名
  2. 類和特質以大駝峰命名
  3. 常量使用全大寫命名
  4. 一般使用兩格縮進
  5. 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

參考鏈接

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 人生苦多,快來 Kotlin ,快速學習Kotlin! 什么是Kotlin? Kotlin 是種靜態類型編程...
    任半生囂狂閱讀 26,267評論 9 118
  • [toc] 0 hello world or 1變量 val 定義 immutable variable var ...
    brother阿張閱讀 320評論 0 0
  • 讀《快學Scala 》一書的摘要 Scala 運行于JVM之上,擁有海量類庫和工具,兼顧函數式編程和面向對象。 在...
    abel_cao閱讀 1,291評論 0 8
  • 生活中我們最常說的是忙,沒有時間!想看書時,沒有時間;想陪家人時,沒有時間;想去旅游時,沒有時間;想要運動時,還是...
    莫莫queen閱讀 166評論 0 0
  • 夏至未至的時節,從Suki老師《穿衣有道,品型識人》的小班課走出來,看著天色尚早,天氣尚好,身后是意猶未盡的姑娘們...
    卿瘋閱讀 830評論 18 15