Scala-变量声明、常用类型、条件与块表达式、循环、方法函数的

2019-04-20  本文已影响0人  weare_b646

为了方便且内容显示更清楚,这里大部分都是使用scala的shell操作
1、Scala变量声明

//使用val定义的变量值是不可变的,相当于java里用final修饰的变量,鼓励使用val
scala> val i = 1
i: Int = 1

//再给i重新赋值就不允许了
scala> i = 2
<console>:8: error: reassignment to val
       i = 2
         ^

//使用var定义的变量是可变得
scala> var j = 1
j: Int = 1

scala> j=2
j: Int = 2

//Scala编译器会自动推断变量的类型
scala> val str = "hello"
str: String = hello

//必要的时候可以指定类型,格式为 变量名 :类型 = 内容
scala> val str2 : String = "scala"
str2: String = scala

2、Scala常用类型
Scala和Java一样,有7种数值类型Byte、Char、Short、Int、Long、Float和Double(无包装类型)和一个Boolean类型
比如上面定义的有Int类型和String类型

//定义Double类型
scala> val db = 3.14
db: Double = 3.14

//定义Boolean类型
scala> val b = true
b: Boolean = true

3、条件表达式
if,else if,else

//定义Int类型的a,值为1
scala> val a = 1
a: Int = 1

//如果a>0 则将a的值赋给b否则将0的值赋给b
scala> val b = if(a > 0) a else 0
b: Int = 1

scala> val b = if(a > 1) a else 0
b: Int = 0

//支持混合类型表达式,如果a>1不成立,那么String类型的error赋给b
scala> val b = if(a > 1) a else "error"
b: Any = error

//如果缺失else,相当于if (x > ) a else ()
//在scala中每个表达式都有值,scala中有个Unit类,写做(),相当于Java中的void
scala> val b = if(a > 1) a
b: AnyVal = ()

scala> val b = if(a > 1) a else ()
b: AnyVal = ()

//if和else if和else
scala> val b = if(a > 2) "r" else if (a >0 ) a else "error"

scala类型系统以Any为根,分为AnyRefAnyVal 两个分支体系,在AnyRef分支的最底层,有个Null类型的特殊类型,它被当作是所有AnyRef类型的子类型。
更进一步在两个分支共同的最底层类型是Nothing类型,它被当作所有AnyRefAnyVal类型的子类型。

image

使用同样的代码在安装了scala的idea里面执行

object HelloScala {////object表示块里面都是静态方法和静态变量

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

    val a = 1;
    val b = if (a > 0) a else 0
    println(b)

    val c = if (a > 1) a else 0
    println(c)

    val d = if (a > 1) a else "error"
    println(d)

    val e = if (a > 1) a
    println(e)

    val f = if (a > 1) a else ()
    println(f)

    val g = if (a > 1) "r" else  if (a > 0) a else "error"
    println(g)

  }
}

输出

1
0
error
()
()
1

3、块表达式
在scala中{}中可包含一系列表达式,块中最后一个表达式的值就是块的值,如下就是一个块的表达式

scala> val res = {
     | if(a > 1){
     |  1
     | }else if (a < 0){
     |    -1
     | }else{
     |   0
     |   }
     | }
res: Int = 0

idea中

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

      val a = 1;

      val res = {
        if (a > 1){
          1
        }else if(a < 0){
          -1
        }else {
          0
        }
      }
    println(res)
}

4、for循环
Scala中有for循环跟while循环,而for循环用的多
for(变量 <- 表达式 )注:表达式通常指的是一个Range(区间),Array(数组),集合等

//表达式1 to 10返回一个Range(区间)
scala> val r = 1 to 10
r: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
//每次循环一次从r这个区间中取出一个成员赋给i,类似于java的增强的for循环
scala> for(i <- r){
     | println(i)
     | }

//使用数组
scala> var arr = Array("hadoop","storm","spark")
arr: Array[String] = Array(hadoop, storm, spark)

scala> for (i <- arr){
     | print(i+" ")
     | }
hadoop storm spark

//带条件的for循环
scala> for(i <- r; if i % 2 == 0){
     | print((i * 10) + " ")
     | }
20 40 60 80 100

//for推导式:如果for循环的循环体以yield开始,则该循环会构建出一个集合,每次迭代生成集合中的一个值
scala> val arr2 = for (i <- r) yield i*10
arr2: scala.collection.immutable.IndexedSeq[Int] = Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)

scala> arr2
res4: scala.collection.immutable.IndexedSeq[Int] = Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)

5、map、filter和until的使用
关于for的推导式,有更好用的办法,那就是使用map()

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

//_表示r中的元素,表示将r中的元素依次取出来乘以10放到新的集合中
scala> val arr3 = r.map(_*10)
arr3: scala.collection.immutable.IndexedSeq[Int] = Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)

scala> arr3
res6: scala.collection.immutable.IndexedSeq[Int] = Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)

但是如果需要带有过滤条件呢,如下

scala> val arr2 = for (i <- r;if i % 2 != 0) yield i*10
arr2: scala.collection.immutable.IndexedSeq[Int] = Vector(10, 30, 50, 70, 90)

scala> arr2
res3: scala.collection.immutable.IndexedSeq[Int] = Vector(10, 30, 50, 70, 90)

这时可以使用filter()

//filter里面是个条件表达式,用来做过滤,将r中的元素取出判断,符合条件的放到新的集合中
scala> val arr4 = r.filter(_ % 2 != 0).map(_ * 10)
arr4: scala.collection.immutable.IndexedSeq[Int] = Vector(10, 30, 50, 70, 90)

scala> arr4
res8: scala.collection.immutable.IndexedSeq[Int] = Vector(10, 30, 50, 70, 90)

如果想跟java那样根据角标取值呢

//获取range的长度,根据根据角标去取
scala> for(i <- 0 to r.length-1) println(r(i))
1
2
3
4
5
6
7
8
9
10

上面使用了r.length-1来获取最大角标,但是scala还给我们提供了until可以直接获取角标范围了

scala> 0 until r.length
res15: scala.collection.immutable.Range = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> for(i <- 0 until r.length) println(r(i))
1
2
3
4
5
6
7
8
9
10

6、方法和函数的调用
Scala中的+ - * / %等操作符的作用与Java一样,位操作符 & | ^ >> <<也一样。只是有
一点特别的:这些操作符实际上是方法。例如:
a + b
是如下方法调用的简写:
a.+(b)
a 方法 b可以写成 a.方法(b)

scala> 1 + 2
res17: Int = 3

scala> 1.+(2)
warning: there were 1 deprecation warning(s); re-run with -deprecation for details
res18: Double = 3.0

scala> 1.-(2)
warning: there were 1 deprecation warning(s); re-run with -deprecation for details
res19: Double = -1.0

两个整数加减结果成了Double类型,只需要前面一个数自己指定为Int类型即可,如下

scala> val m = 1
m: Int = 1

scala> m.-(2)
res20: Int = -1

上一篇下一篇

猜你喜欢

热点阅读