從零開始學(xué)習(xí)Spark(二)Scala基礎(chǔ)

Scala基礎(chǔ)

Spark的原生語言是Scala,因此入門一下Scala是學(xué)習(xí)Spark的第一步,下面就快速入門一下待错,爭取不花太多的時間。之后的簡書中還會有Scala進階烈评,交代一些其他特性火俄。這篇Scala基礎(chǔ)應(yīng)該可以暫時應(yīng)付之后Spark的學(xué)習(xí)。

  • Scala運行在JVM上
  • Scala是純面向?qū)ο蟮恼Z言
  • Scala是函數(shù)式編程語言
  • Scala是靜態(tài)類型語言

1. HelloWorld

object HelloWorld {
    def main(args: Array[String]): Unit = {
        println("Hello, world!")
    }
}

2. 交互式編程與腳本形式

交互式編程進入方式有兩種础倍,terminal中輸入scala,或者輸入sbt再輸入console

腳本形式則類似Java的編譯形式

$ scalac HelloWorld.scala
$ scala HelloWorld.scala

scalac編譯生成.class文件胎挎,注意可以跳過這一步沟启,直接使用scala來執(zhí)行

3. Scala包

定義包

package com.runoob
class HelloWorld

第二種定義包的方法,可以一個文件中定義多個包

package com.runoob {
  class HelloWorld 
}

源文件的目錄和包之間并沒有強制的關(guān)聯(lián)關(guān)系犹菇。你不需要將Employee.scala放在com/horstmann/impatient目錄當(dāng)中

package com {
  package horstmann {
    package impatient {
      class Manager
        ......
    }
  }
}

引用包

import com.runoob.HelloWorld
import java.awt._    //引入包內(nèi)所有成員

注意scala中類和對象一般用大寫字母開頭

4. Scala變量與數(shù)據(jù)類型

數(shù)據(jù)類型

只羅列幾個特殊的德迹,注意所有的數(shù)據(jù)類型都是對象

  • Byte, Short, Int(默認(rèn)), Long, Float, Double(默認(rèn)), Char, String
  • Unit 表示無值,和其他語言中void等同揭芍。用作不返回任何結(jié)果的方法的結(jié)果類型胳搞。Unit只有一個實例值,寫成()称杨。
  • Null null 或空引用
  • Nothing Nothing類型在Scala的類層級的最低端肌毅;它是任何其他類型的子類型。
  • Any Any是所有其他類的超類
  • AnyRef AnyRef類是Scala里所有引用類(reference class)的基類

變量和常量

在 Scala 中姑原,使用關(guān)鍵詞 "var" 聲明變量悬而,使用關(guān)鍵詞 "val" 聲明常量

var myVar: String = "Foo"
var myVar2: Int //變量聲明不一定要初始值
val myVal: String = "Too"  //常量不能修改
var myVar = 10;  //常量和變量的聲明不一定要指明數(shù)據(jù)類型,編譯器會自己推斷
val myVal = "Hello, Scala!";  

還可以聲明一個元組锭汛,變量常量都可以

scala> val pa = (40,"Foo")
pa: (Int, String) = (40,Foo)

5. Scala訪問修飾符

Scala訪問權(quán)限

  • private:僅在包含了成員定義的類或?qū)ο髢?nèi)部可見笨奠。Java中允許這兩種訪問袭蝗,因為它允許外部類訪問內(nèi)部類的私有成員。
class Outer{
    class Inner{
      private def f(){println("f")}
    class InnerMost{
        f() // 正確
        }
    }
    (new Inner).f() //錯誤
}
  • protected:只允許保護成員在定義了該成員的的類的子類中被訪問般婆。而在java中到腥,用protected關(guān)鍵字修飾的成員,除了定義了該成員的類的子類可以訪問蔚袍,同一個包里的其他類也可以進行訪問乡范。
package p{
    class Super{
        protected def f() {println("f")}
    }
    class Sub extends Super{
        f()
    }
    class Other{
        (new Super).f() //錯誤
    }
}
  • public:Scala中,如果沒有指定任何的修飾符页响,則默認(rèn)為 public篓足。這樣的成員在任何地方都可以被訪問。

JAVA的訪問權(quán)限表

  • public--都可訪問(公有)

  • protected--包內(nèi)和子類可訪問(保護)

  • 不寫(default)--包內(nèi)可訪問 (默認(rèn))

  • private--類內(nèi)可訪問(私有)

作用域保護

private[x]protected[x]

這里的x指代某個所屬的包闰蚕、類或單例對象栈拖。如果寫成private[x],讀作"這個成員除了對[…]中的類或[…]中的包中的類及它們的伴生對像可見外,對其它所有類都是private没陡。

6. 運算符涩哟,條件,循環(huán)

和JAVA基本相同盼玄,舉幾個for循環(huán)使用的例子

<-表示為變量賦值贴彼,to表示包含后面的值

for( a <- 1 to 10){
  println( "Value of a: " + a );
}

until表示不包含后面的值

for( a <- 1 until 10){
  println( "Value of a: " + a );
}

在 for 循環(huán) 中你可以使用分號 (;) 來設(shè)置多個區(qū)間,它將迭代給定區(qū)間所有的可能值埃儿。

for( a <- 1 to 3; b <- 1 to 3){
  println( "Value of a: " + a );
  println( "Value of b: " + b );
}

for 循環(huán)會迭代所有集合的元素

val numList = List(1,2,3,4,5,6);
for( a <- numList ){
  println( "Value of a: " + a );
}

for循環(huán)還可以加入條件過濾

val numList = List(1,2,3,4,5,6,7,8,9,10);
// 下面的代碼會輸出1,2,4,5,6,7
for( a <- numList
  if a != 3; if a < 8 ){
  println( "Value of a: " + a );
}

利用yield來產(chǎn)生集合器仗,和python不一樣的

val numList = List(1,2,3,4,5,6,7,8,9,10);
// 下面的代碼會輸出1,2,4,5,6,7
var retVal =  for( a <- numList
  if a != 3; if a < 8 )yield a

retVal: List[Int] = List(1, 2, 4, 5, 6, 7)

7. 函數(shù)

聲明

def functionName ([參數(shù)列表]) : [return type]

定義

def functionName ([參數(shù)列表]) : [return type] = {
   function body
   return [expr]
}

如果函數(shù)沒有返回值,可以返回為 Unit童番,這個類似于 Java 的 void

例子

object Test {
    def main(args: Array[String]) {
        println("Hello\tWorld\n\n")
        println("3 + 4 = " + add(3, 4))
    }
    def add(a: Int, b: Int): Int = {
        var sum: Int = a + b
        return sum
    }
}

8. 函數(shù)高級特性

傳名調(diào)用

傳名調(diào)用(Call-by-name):參數(shù)傳入時精钮,不事先計算,而是將表達(dá)式子代入其中

傳入?yún)?shù)時要用=>

object Test {
   def main(args: Array[String]) {
        delayed(time());
   }

   def time() = {
      println("獲取時間剃斧,單位為納秒")
      System.nanoTime
   }
   def delayed( t: => Long ) = {
      println("在 delayed 方法內(nèi)")
      println("參數(shù): " + t)
      t
   }
}

這個時候轨香,相當(dāng)于函數(shù)中的每個t都編程time(),所以輸出會變成

在 delayed 方法內(nèi)
獲取時間幼东,單位為納秒
參數(shù): 241550840475831
獲取時間臂容,單位為納秒

可變參數(shù)

Scala 允許你指明函數(shù)的最后一個參數(shù)可以是重復(fù)的,即我們不需要指定函數(shù)參數(shù)的個數(shù)根蟹,可以向函數(shù)傳入可變長度參數(shù)列表脓杉。

Scala 通過在參數(shù)的類型之后放一個星號來設(shè)置可變參數(shù)(可重復(fù)的參數(shù))。

object Test {
   def main(args: Array[String]) {
        printStrings("Runoob", "Scala", "Python");
   }
   def printStrings( args:String* ) = {
      var i : Int = 0;
      for( arg <- args ){
         println("Arg value[" + i + "] = " + arg );
         i = i + 1;
      }
   }
}

高階函數(shù)

高階函數(shù)(Higher-Order Function)就是操作其他函數(shù)的函數(shù)简逮。

object Test {
   def main(args: Array[String]) {
      println( apply( layout, 10) )
   }
   // 函數(shù) f 和 值 v 作為參數(shù)丽已,而函數(shù) f 又調(diào)用了參數(shù) v
   def apply(f: Int => String, v: Int) = f(v)
   def layout[A](x: A) = "[" + x.toString() + "]"
}

偏應(yīng)用函數(shù)

實際上就是固定函數(shù)的某些參數(shù)生成新的函數(shù),使用下劃線(_)替換缺失的參數(shù)列表

import java.util.Date
object Test {
   def main(args: Array[String]) {
      val date = new Date
      val logWithDateBound = log(date, _ : String) //logWithDateBound就變成函數(shù)了
      logWithDateBound("message1" )
      Thread.sleep(1000)
      logWithDateBound("message2" )
      Thread.sleep(1000)
      logWithDateBound("message3" )
   }
   def log(date: Date, message: String)  = {
     println(date + "----" + message)
   }
}

匿名函數(shù)

相當(dāng)于python中的lambda

var inc = (x:Int) => x+1
var mul = (x: Int, y: Int) => x*y
var userDir = () => { System.getProperty("user.dir") }
//調(diào)用
var x = inc(7)-1
println(mul(3, 4))
println(userDir())

函數(shù)柯里化(Currying)

def add(x:Int)(y:Int) = x + y
// 調(diào)用
var a = add(1)(2)

add(1)(2) 實際上是依次調(diào)用兩個普通函數(shù)(非柯里化函數(shù))买决,第一次調(diào)用使用一個參數(shù) x沛婴,返回一個函數(shù)類型的值吼畏,第二次使用參數(shù)y調(diào)用這個函數(shù)類型的值。

參考資料

Scala教程 - 菜鳥教程

Scala學(xué)習(xí)(七)---包和引入

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嘁灯,一起剝皮案震驚了整個濱河市泻蚊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌丑婿,老刑警劉巖性雄,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異羹奉,居然都是意外死亡秒旋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門诀拭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來迁筛,“玉大人,你說我怎么就攤上這事耕挨∠肝裕” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵筒占,是天一觀的道長贪庙。 經(jīng)常有香客問我,道長翰苫,這世上最難降的妖魔是什么止邮? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮奏窑,結(jié)果婚禮上导披,老公的妹妹穿的比我還像新娘。我一直安慰自己良哲,他們只是感情好盛卡,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布助隧。 她就那樣靜靜地躺著筑凫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪并村。 梳的紋絲不亂的頭發(fā)上巍实,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機與錄音哩牍,去河邊找鬼棚潦。 笑死,一個胖子當(dāng)著我的面吹牛膝昆,可吹牛的內(nèi)容都是我干的丸边。 我是一名探鬼主播叠必,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼妹窖!你這毒婦竟也來了纬朝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤骄呼,失蹤者是張志新(化名)和其女友劉穎共苛,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜓萄,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年辟犀,在試婚紗的時候發(fā)現(xiàn)自己被綠了踪蹬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片臣咖。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖疚漆,靈堂內(nèi)的尸體忽然破棺而出刁赦,到底是詐尸還是另有隱情,我是刑警寧澤甚脉,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布狡耻,位于F島的核電站猴凹,受9級特大地震影響夷狰,放射性物質(zhì)發(fā)生泄漏沼头。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一土至、第九天 我趴在偏房一處隱蔽的房頂上張望毙籽。 院中可真熱鬧,春花似錦坑赡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捆探。三九已至站粟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奴烙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留幅虑,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓褒墨,卻偏偏與公主長得像哄芜,于是被迫代替她去往敵國和親柬唯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容