从零开始学习Spark(二)Scala基础

Scala基础

Spark的原生语言是Scala,因此入门一下Scala是学习Spark的第一步,下面就快速入门一下,争取不花太多的时间。之后的简书中还会有Scala进阶,交代一些其他特性。这篇Scala基础应该可以暂时应付之后Spark的学习。

  • Scala运行在JVM上
  • Scala是纯面向对象的语言
  • Scala是函数式编程语言
  • Scala是静态类型语言

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来执行

3. Scala包

定义包

package com.runoob
class HelloWorld

第二种定义包的方法,可以一个文件中定义多个包

package com.runoob {
  class HelloWorld 
}

源文件的目录和包之间并没有强制的关联关系。你不需要将Employee.scala放在com/horstmann/impatient目录当中

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

引用包

import com.runoob.HelloWorld
import java.awt._    //引入包内所有成员

注意scala中类和对象一般用大写字母开头

4. Scala变量与数据类型

数据类型

只罗列几个特殊的,注意所有的数据类型都是对象

  • Byte, Short, Int(默认), Long, Float, Double(默认), Char, String
  • Unit 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。
  • Null null 或空引用
  • Nothing Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。
  • Any Any是所有其他类的超类
  • AnyRef AnyRef类是Scala里所有引用类(reference class)的基类

变量和常量

在 Scala 中,使用关键词 "var" 声明变量,使用关键词 "val" 声明常量

var myVar: String = "Foo"
var myVar2: Int //变量声明不一定要初始值
val myVal: String = "Too"  //常量不能修改
var myVar = 10;  //常量和变量的声明不一定要指明数据类型,编译器会自己推断
val myVal = "Hello, Scala!";  

还可以声明一个元组,变量常量都可以

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

5. Scala访问修饰符

Scala访问权限

  • private:仅在包含了成员定义的类或对象内部可见。Java中允许这两种访问,因为它允许外部类访问内部类的私有成员。
class Outer{
    class Inner{
      private def f(){println("f")}
    class InnerMost{
        f() // 正确
        }
    }
    (new Inner).f() //错误
}
  • protected:只允许保护成员在定义了该成员的的类的子类中被访问。而在java中,用protected关键字修饰的成员,除了定义了该成员的类的子类可以访问,同一个包里的其他类也可以进行访问。
package p{
    class Super{
        protected def f() {println("f")}
    }
    class Sub extends Super{
        f()
    }
    class Other{
        (new Super).f() //错误
    }
}
  • public:Scala中,如果没有指定任何的修饰符,则默认为 public。这样的成员在任何地方都可以被访问。

JAVA的访问权限表

  • public--都可访问(公有)

  • protected--包内和子类可访问(保护)

  • 不写(default)--包内可访问 (默认)

  • private--类内可访问(私有)

作用域保护

private[x]protected[x]

这里的x指代某个所属的包、类或单例对象。如果写成private[x],读作"这个成员除了对[…]中的类或[…]中的包中的类及它们的伴生对像可见外,对其它所有类都是private。

6. 运算符,条件,循环

和JAVA基本相同,举几个for循环使用的例子

<-表示为变量赋值,to表示包含后面的值

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

until表示不包含后面的值

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

在 for 循环 中你可以使用分号 (;) 来设置多个区间,它将迭代给定区间所有的可能值。

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

for 循环会迭代所有集合的元素

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

for循环还可以加入条件过滤

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来产生集合,和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. 函数

声明

def functionName ([参数列表]) : [return type]

定义

def functionName ([参数列表]) : [return type] = {
   function body
   return [expr]
}

如果函数没有返回值,可以返回为 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. 函数高级特性

传名调用

传名调用(Call-by-name):参数传入时,不事先计算,而是将表达式子代入其中

传入参数时要用=>

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

   def time() = {
      println("获取时间,单位为纳秒")
      System.nanoTime
   }
   def delayed( t: => Long ) = {
      println("在 delayed 方法内")
      println("参数: " + t)
      t
   }
}

这个时候,相当于函数中的每个t都编程time(),所以输出会变成

在 delayed 方法内
获取时间,单位为纳秒
参数: 241550840475831
获取时间,单位为纳秒

可变参数

Scala 允许你指明函数的最后一个参数可以是重复的,即我们不需要指定函数参数的个数,可以向函数传入可变长度参数列表。

Scala 通过在参数的类型之后放一个星号来设置可变参数(可重复的参数)。

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;
      }
   }
}

高阶函数

高阶函数(Higher-Order Function)就是操作其他函数的函数。

object Test {
   def main(args: Array[String]) {
      println( apply( layout, 10) )
   }
   // 函数 f 和 值 v 作为参数,而函数 f 又调用了参数 v
   def apply(f: Int => String, v: Int) = f(v)
   def layout[A](x: A) = "[" + x.toString() + "]"
}

偏应用函数

实际上就是固定函数的某些参数生成新的函数,使用下划线(_)替换缺失的参数列表

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

匿名函数

相当于python中的lambda

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

函数柯里化(Currying)

def add(x:Int)(y:Int) = x + y
// 调用
var a = add(1)(2)

add(1)(2) 实际上是依次调用两个普通函数(非柯里化函数),第一次调用使用一个参数 x,返回一个函数类型的值,第二次使用参数y调用这个函数类型的值。

参考资料

Scala教程 - 菜鸟教程

Scala学习(七)---包和引入

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容