Scala 2.11.8安装部署和基本语法一

1 下载地址

2 安装部署

  • 下载
[root@zhangyu software]# wget https://downloads.lightbend.com/scala/2.11.8/scala-2.11.8.zip
  • 解压
[root@zhangyu software]# unzip scala-2.11.8.zip
  • 配置环境变量
[root@zhangyu ~]# vi /etc/profile
export SCALA_HOME=/opt/software/scala-2.11.8
export PATH=$SCALA_HOME/bin:$PATH
生效配置文件:
[root@zhangyu ~]# source /etc/profile
  • 启动
[root@zhangyu ~]# scala -version
Scala code runner version 2.11.8 -- Copyright 2002-2016, LAMP/EPFL

[root@zhangyu ~]# scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45).
Type in expressions for evaluation. Or try :help.

scala> 

3 基本语法

  • 学习前我们先提出一个问题,为什么要学习Scala语言呢?
  1. 第一肯定是为了学习后面的Spark,因为Spark底层是用Scala实现;
  2. 对于作者来说是有一定java的基础的,刚开始接触Scala给我的感觉就是语言很简洁,优雅,开发速度快,给我的感觉就是很强大,有种让人不可思议的感觉;
  3. 能够融合到大数据生态圈。
  4. Scala是运行在JVM上的,所以Scala中也可以写java代码,所以很多java的工具类,也可以使用。
  • 简单了解Scala
  1. Scala是基于Java虚拟机(JVM)的一门编程语言,所有Scala的代码需经过编译为字节码,然后交由Java虚拟机来运行,所以Scala可以任意调用Java的代码和引用Jar包。
  2. 本文为大家介绍了 Scala 的基本语法,相比 Java,Scala 的语法更加简洁,比如 Scala 的类型推断可以省略程序中绝大多数的类型声明,短小精悍的匿名函数可以方便的在函数之间传递,还有各种在 Scala 社区约定俗成的习惯,比如省略的分号以及函数体只有一条表达式时的花括号,这一切都帮助程序员写出更简洁,更优雅的程序,下面我们一起进行简单的学习。
3数据类型
Scala有8种数据类型:
Boolean:true/false
Byte:8位,有符号
Short:16位,有符号
Int:32位,有符号
Long:64位,有符号
Char:16位,无符号
Float:32位,单精度浮点数
Double:64位,双精度浮点数

Scala 中所有值都是类对象,所有的类都继承统一的根类 Any:
在这里插入图片描述
Null 是所有引用类型的子类型 , Nothing是所有类型的子类型.

3.1内置变量
scala> 1+2
res0: Int = 3

scala> val array = Array(1,2,3,4)
array: Array[Int] = Array(1, 2, 3, 4)

scala> array(0) = 5

scala> array
res1: Array[Int] = Array(5, 2, 3, 4)
scala> res0+5
res1: Int = 8

上面res0就是内存变量,可用res0变量参与公式计算或字符串拼接。如输入res0+5或"hello:res0"

3.2变量声明

Scala具有用于声明变量的不同语法。它们可以被定义为值,即常数或变量。

  • val(常量声明):不可变
scala> val x:Int=0
x: Int = 0
  • var(变量声明):可变
scala> var y:String="Hello Scala"
y: String = Hello Scala

现在我们尝试改变x,y的值,会有什么不同:

scala> x=1;
<console>:12: error: reassignment to val
       x=1;
        ^
给常量赋值会出现编译错误

scala> y="haha"
y: String = haha
  • 下面我们再试试如果不给常量或者变量声明类型会报错吗?
    可变类型推断
scala> val x1=1
x1: Int = 1

scala> var y1="hello"
y1: String = hell0
默认情况下,x1将会被计算推断为Int类型,y1将计算推断为String类型变量。
  1. 定义变量时没有指定变量类型。这是否意味着 Scala 是和 Python 或者 Ruby 一样的动态类型语言呢?恰恰相反,Scala 是严格意义上的静态类型语言,由于其采用了先进的类型推断(Type Inference)技术,程序员不需要在写程序时显式指定类型,编译器会根据上下文推断出类型信息。比如变量 x被赋值为 0,0 是一个整型,所以 x的类型被推断出为整型。当然,Scala 语言也允许显示指定类型,如变量 x1,y1的定义。一般情况下,我们应尽量使用 Scala 提供的类型推断系统使代码看上去更加简洁。
  2. 另一个发现是程序语句结尾没有分号,这也是 Scala 中约定俗成的编程习惯。大多数情况下分号都是可省的,如果你需要将两条语句写在同一行,则需要用分号分开它们。

val的再次理解

scala> val array = Array(1,2,3,4)
array: Array[Int] = Array(1, 2, 3, 4)

scala> array(0) = 5

scala> array
res1: Array[Int] = Array(5, 2, 3, 4)

上面我们说了val是申明不可变变量的,但在这里我们声明了一个array但是我们又修改了值,并没有报错.是不是很奇怪呢?

val 和var关键字只标识引用本身是否可以指向另外一个不同的对象,他们并没有表明所引用的对象是否可变. 为了减少可变性引起的bug,应该尽量使用不可变变量

val 和var在声明变量时都必须初始化

3.3多个赋值
  • Scala支持多个赋值。如果代码块或方法返回一个元素数组(Tuple - 保持不同类型的对象的集合),则可以将元素数组分配给一个val变量。
    :我们将在随后的章节学习元组。
scala> val (myVar1:Int,myVar2:String)=Pair(22,"Hello")
warning: there was one deprecation warning; re-run with -deprecation for details
myVar1: Int = 22
myVar2: String = Hello

类型推断得到正确的类型
scala> val (myVar11,myVar22)=Pair(22,"Hello")
warning: there was one deprecation warning; re-run with -deprecation for details
myVar11: Int = 22
myVar22: String = Hello
3.4 强制类型转换

Scala中不像java可以进行强制类型转化,需要通过方法进行:

to               toChar      toFloat       toLong          toShort
toBinaryString   toDegrees   toHexString   toOctalString   toString
toByte           toDouble    toInt         toRadians
  • to…
定义一个常量:
scala> val c=10
c: Int = 10  (自动推测为Int类型)

强转:
scala> 10.to  这是按Tab键查看如下函数
to               toChar      toFloat       toLong          toShort    
toBinaryString   toDegrees   toHexString   toOctalString   toString   
toByte

scala> 10.toDouble
res1: Double = 10.0
  • asInstanceOf

scala> val a=2
a: Int = 2

scala> a.asInstanceOf[Double]
res4: Double = 2.0
  • isInstanceOf
scala> a.isInstanceOf[Int]
res5: Boolean = true

scala> a.isInstanceOf[Double]
res6: Boolean = false
3.5 定义函数
  • 语法:
def functionName ([list of parameters]) : [return type] = {
   function body
   return [expr]
}
这里,返回类型可以是任何有效的Scala数据类型,参数列表将是由逗号分隔的变量列表,参数列表和返回类型是可选的。

1.带参数没有返回值

scala> def test1(x:Int) : Unit={println(x+x)}
test1: (x: Int)Unit

scala> test1(2)
4

2.带参数带返回值

scala> def add(x:Int):Int={x+x}
add: (x: Int)Int

scala> add(2)
res4: Int = 4

3.无参无返回值


scala> def sayHello():Unit=println("hello word")
sayHello: ()Unit

scala> sayHello()
hello word

scala> sayHello  如果没有入参括号都可以省略,是不是很强大,很神奇。
hello word

总结:首先,函数体没有像 Java 那样放在 {}里。Scala 中的一条语句其实是一个表达式,函数的执行过程就是对函数体内的表达式的求值过程,最后一条表达式的值就是函数的返回值。如果函数体只包含一条表达式,则可以省略 {}。其次,没有显示的 return语句,最后一条表达式的值会自动返回给函数的调用者。

3.6 HelloWorld.scala
  • 在java中我们对于一个java文件需要使用javac编译成class文件,那么scala中其实和java也是一样的,下面来学习我们经典的Hello World例子。
[hadoop@zhangyu ~]$ vi Hello.scala

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello World")
  }
}

编译:
[hadoop@zhangyu ~]$ scalac ~/Hello.scala 

查看生成的class文件:
-rw-rw-r--.  1 hadoop hadoop    88 Feb  3 23:03 Hello.scala
-rw-rw-r--.  1 hadoop hadoop   581 Feb  3 23:05 HelloWorld.class
-rw-rw-r--.  1 hadoop hadoop   630 Feb  3 23:05 HelloWorld$.class
可以看到生成了class文件

结果:
[hadoop@zhangyu ~]$ scala HelloWorld
Hello World
  • Scala 还提供了一个更简便的方式,直接继承另一个对象 App,无需定义 main方法,编译即可运行。
 object HelloScala extends App { 
  println("Hello Scala!") 
 }
3.7 lazy关键字

Scala中使用关键字lazy来定义惰性变量,实现延迟加载(懒加载)。 惰性变量只能是不可变变量,并且只有在调用惰性变量时,才会去实例化这个变量。
java中也有懒加载,java中的单例模式大家应该在熟悉不过来(懒汉模式,饿汉模式),作者以前的博客中也有所解释,有兴趣的同学可以看一看。这里我们主要看看scala中懒加载。
注意: lazy只能修饰常量,不能修饰变量

  • 不使用lazy关键字对常量修饰
object LazyOptions {
  def init(): Unit ={
    println("你好,我是init")
  }

  def main(args: Array[String]): Unit = {
    //定义一个常量
    val property1 = init() //没有使用lazy修饰
    println("哈哈")
  }
}

上面的property1没有使用lazy关键字进行修饰,所以property是立即实例化的,观察程序的输出:
你好,我是init
哈哈
  • 使用lazy关键字进行修饰:
object LazyOptions {
  def init(): Unit ={
    println("你好,我是init")
  }

  def main(args: Array[String]): Unit = {
    //定义一个常量
//    val property1 = init() //没有使用lazy修饰
//    println("哈哈")

    lazy val property2= init()
    println("哈哈")
    println(property2)
  }
}
这时property2使用了lazy关键字修饰,我们来看看输出结果:
哈哈
你好,我是init
()

在声明property2时,并没有立即调用实例化方法intit(),而是在使用property2时,才会调用实例化方法,并且无论缩少次调用,实例化方法只会执行一次。

Scala同样使用了Java中常用的懒加载的方式自动帮助我们实现了延迟加载,并且还加锁避免多个线程同时调用初始化方法可能导致的不一致问题。

3.8 迭代
  • to(左闭右闭)
scala> 1 to 5
res9: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)

scala> 1.to(5)
res10: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)
  • Range(左闭右开)
scala> Range(1,10)
res16: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> Range(1,10,1)
res17: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> Range(1,10,2)
res18: scala.collection.immutable.Range = Range(1, 3, 5, 7, 9)

scala> Range(10,1,-1)
res20: scala.collection.immutable.Range = Range(10, 9, 8, 7, 6, 5, 4, 3, 2)
  • until(左闭右开)
scala> 1 until 10
res23: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
和Range是一样的
3.9 流程控制语句
  • 使用 if else 表达式
def abs(n: Int): Int = 
 if (n > 0) n else -n

scala> val x =  5
x: Int = 5

scala> val s = if(x>0) 1 else -1
s: Int = 1
scala> val s = if(x>1) "a" else ()
s: Any = a

scala> val x = -1
x: Int = -1

scala> val s = if(x>1) "a" else ()
s: Any = ()
  • 使用 while 为列表求和
def sum(xs: List[Int]) = { 
    var total = 0 
    var index = 0 
    while (index < xs.size) { 
      total += xs(index) 
      index += 1 
    } 
    total 
  }
  • for循环(重点
    语法结构for (i <- 表达式)
    让变量i遍历右边的表达式的所有值。至于这个遍历具体如何执行,则取决于表达式的类型。对于Scala集合比如Range而言,这个循环会让i依次取得区间中的每个值。

说明:在for循环的变量之前并没有val或var的指定。该变量的类型是集合的元素类型。循环变量的作用域一直持续到循环结束。

  • 最简单的语法
object For extends App{

     for (i <- 1 to 5){
       println(i)
     }

}

结果:
1
2
3
4
5
  • 您可以在for循环中使用由分号(;)分隔的多个范围,在这种情况下,循环将遍历给定范围所有可能的计算。以下是仅使用两个范围的示例,也可以使用两个以上的范围。
object For extends App{

     for (i <- 1 to 3;j <- 1 to 3){
       println("i"+":"+i)
       println("j"+":"+j)
     }

}

结果:
i:1
j:1
i:1
j:2
i:1
j:3
i:2
j:1
i:2
j:2
i:2
j:3
i:3
j:1
i:3
j:2
i:3
j:3
  • 遍历集合中的元素
object For extends App{
  var sum=0
  val numList = List(1, 2, 3, 4, 5, 6)
  for (i <- numList){
    sum+=i
    println(i)
  }
println(sum);
}

结果:
1
2
3
4
5
6
21
  • for循环允许过滤出使用一个或多个某些元素if语句(多个)。
var a = 0;
  val numList = List(1,2,3,4,5,6,7,8,9,10);

  // for loop execution with multiple filters
  for( a <- numList
       if a != 3; if a < 8 ){
    println( "Value of a: " + a );
  }
结果:
Value of a: 1
Value of a: 2
Value of a: 4
Value of a: 5
Value of a: 6
Value of a: 7
scala> for(i <- 1 to 5; x = 10-i) print(x + " ")
9 8 7 6 5
  • for循环与yield
    需要返回值怎么办呢?
    这时候就可以使用yield,使用yield关键值能在for循环中生成新的集合,集合中的元素会根据类型推到而出.
 var a = 0;
      val numList = List(1,2,3,4,5,6,7,8,9,10);

      // for loop execution with a yield
      var retVal = for{ a <- numList if a != 3; if a < 8 }
      yield a

      // Now print returned values using another loop.
      for( a <- retVal){
         println( "Value of a: " + a );
      }
   }
结果:
Value of a: 1
Value of a: 2
Value of a: 4
Value of a: 5
Value of a: 6
Value of a: 7
3.10 默认参数/命令参数/变长参数
  • 默认参数
object Params {

  // 默认参数
  def sayName(name: String = "zhangsan"): Unit = {
    println(name)
  }

  def main(args: Array[String]): Unit = {
        sayName("zhangsan")
        sayName("lisi")
        sayName()
  }
}
结果:
zhangsan
lisi
zhangsan
  • 命令参数
object Params {

  // 命令参数
  def speed (distance:Float, time:Float) = distance/time

  def main(args: Array[String]): Unit = {
        println(speed(100, 3))
        println(speed(distance = 100, time = 3))
        println(speed(time = 3, distance = 100))
  }
}

结果:
33.333332
33.333332
33.333332
  • 变长参数
object Params {

  // 变长参数
  def sum(nums: Int*) = {
    var result = 0
    for(num <- nums) {
      result += num
    }
    result
  }


  def main(args: Array[String]): Unit = {

    println(sum(2,3))
    println(sum(2,3,4))
    println(sum(2,3,4,5))
    //  :_*  强转符号
    println(sum(1 to 5 : _*))
  }
}
结果:
5
9
14
15
3.11 option类型

Scala为单个值提供了对象的包装器,表示可能存在也可能不存在的值, Some 表示某个值,None表示空,避免了使用null 和空字符串.

scala> val map = Map("zhangsan"  -> 1, "lisi" -> 2)
map: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 1, lisi -> 2)

scala> map.get("zhangsan")
res8: Option[Int] = Some(1)

scala> val value = map.get("zhangsan")
value: Option[Int] = Some(1)

scala> value
res9: Option[Int] = Some(1)

scala> println(value)
Some(1)

scala> val value1 = map.get("wangwu")
value1: Option[Int] = None

scala> println(value1)
None

//使用getOrElse 可以给定一个默认值,如果可以查不出来就只指定的默认值
scala> val value2 = map.getOrElse("wangwu","aaa")
value2: Any = aaa
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值