Scala基础

变量和函数定义

Scala有两种类型的变量,val和var。val类似于Java里的final类型,一旦初始化就不能再更改值。而var可以多次赋值

scala> val str = "Hello, World"
str:String = Hello, World
scala> var msg = "This is a variable"
msg:String = This is a variable
scala> msg = "This is another variable"
msg:String = This is another variable
scala> str = "Hello, Scala"
<console>:8: error: reassignment to val
       str = "Hello, Scala"
        ^

这里str和msg都是String类型,前面显示是变量名称,冒号”:”后跟着变量的类型,”=”后是变量的值。下面是函数的定义

  def max(x:Int, y:Int):Int = {
    if(x > y)
      x
    else
      y
  }

函数的定义用关键字def开始,上面定义了一个max的函数,输入参数是两个Int类型, x和y。返回值是Int类型,返回x与y中较大值。注意返回时可以不包含关键字return。

函数定义

调用时非常简单

val result = max(1,2)

不带参数和返回值的函数

  def greet()={println("Hello")}

甚至可以省略写成

  def greet = println("Hello")

这个时候函数变得几乎和变量一样。

当然还有匿名函数

scala> (x:Int)=>x+1
res0: Int => Int = <function1>

这个函数输入参数为x,返回x+1

scala> res0(1)
res1: Int = 2

匿名函数在Scala里经常用到,通常作为参数传入函数里。

类和对象

Scala里类和Java里的类很相似,但也有区别。类定义关键字class,创建类用new,这点和Java一样。类里可以包含变量和方法,统称为类的成员。

  class ScalaClass{
    val a = 1
    var b = 0

    def add (x: Int, y:Int) : Int = {
      x + y
    }

    def count():Int = {
      b += 1
      b
    }
  }
  val s = new ScalaClass
  s.add(2,3)
  s.count

而Scala相比于Java,没有静态成员这个说法。Scala有单例对象,单例对象的定义和类差不多,除了关键字用object之外

  object ScalaClass{
    private val a = 1
    val b = 2
    def add: Int = a + b
  }
  val res = ScalaClass.add

当单例对象与某个类共享同一个名称时,他被称作是这个类的伴生对象。但必须在同一个源文件里定义类和伴生对象,类和伴生对象可以互相访问私有成员

基本类型和操作

基本类型

Scala的基本类型和Java基本一致,这里不再赘述

这里写图片描述

操作符和方法

先来看下以下表达式

scala> val a = 1 + 2
a: Int = 3

Scala中并没有内置的运算符,所有的运算法则都是函数,注意这里的”+”号,这是”1”这个Int对象的类成员方法,上面的表达式也可以这样

scala> val a = (1).+ (2)
a: Int = 3

函数可以看作是中缀操作符,所以可以省略写成 val a = 1 + 2, 实际上Scala中的函数都可以当作是操作符。包括前缀操作符,中缀操作符和后缀操作符。前缀操作符只包含 + ,- ,!,~,输入参数是一元的。中缀操作符包含两个输入参数,操作符在两个参数的中间。后缀操作符也是一元的,操作符在输入参数的后边。我们都知道在Java里,Int类型的变量和Long类型的变量相加会安全转换成Long型,而Scala中是通过重载的方式来处理这种转换的,看下Int.scala的源码

  /** Returns the sum of this value and `x`. */
  def +(x: Byte): Int
  /** Returns the sum of this value and `x`. */
  def +(x: Short): Int
  /** Returns the sum of this value and `x`. */
  def +(x: Char): Int
  /** Returns the sum of this value and `x`. */
  def +(x: Int): Int
  /** Returns the sum of this value and `x`. */
  def +(x: Long): Long
  /** Returns the sum of this value and `x`. */
  def +(x: Float): Float
  /** Returns the sum of this value and `x`. */
  def +(x: Double): Double

循环控制

Scala中的循环控制语句相对较少,仅仅包含if, while, for, 和match。主要原因是从一开始Scala就包括了函数文本,而非在基本语法上嵌套高层及的控制结构。Scala几乎所有的控制语句都会产生某个值,有点类似与Java的三元操作符”?:”。
if

  val a = 1
  val b = if(a == 1)2 else 3

if有两个分支,如果a等于1,那么把2赋值给b,否则把3赋值给b。从上面的例子可以看出,判断语句每个分支返回一个特定的值

for
for在Scala中做的最简单的事就是枚举集合中的所有元素

  val str = "Hello, Scala!"
  for(s <- str)println(s)

这里”<-“表示把str中的每个元素枚举一遍,然后依次赋值给s。括号里也可以添加一些控制语句实现过滤和嵌套枚举效果

  val str = "Hello, Scala!"
  for(s <- str if s <= 'h')println(s)

还可以生成一个新的集合,利用关键字yield

  def func():String = {
    val str = "Hello, Scala!"
    for(s <- str if s > 'A';if s <= 'h')yield s
  }

这里调用func,返回的是一个字符串”HeScaa”。 yield可以保存每次枚举的结果,根据需要灵活生成不同的集合类型。只要是可以枚举的对象,都可以用for

while
while的用法和Java一致,唯一的区别是,while语句执行完后会返回一个Unit类型的值,这个Unit类型类似于Java的void类型。

  var t = 10
  while(t > 0 ){
    println(t)
    t -= 1
  }

match
match语句非常有意思,Scala中并没有switch-case,却有match-case. match-case比switch-case强大的多。match可以接受的值不仅限于整数类型和枚举类型,可以是接受几乎任何对象。

  val date = "Monday"
  date match{
    case "Monday" => println(1)
    case "Tuesday" => println(2)
    case "Wednesday" => println(3)
    case "Thursday" => println(4)
    case "Friday" => println(5)
    case "Saturday" => println(6)
    case "Sunday" => println(7)
  }

集合简介

数组
数组的初始化,有两种方式,一种是直接new 一个Array,然后对每一个元素赋值。还有一种是对所有的元素统一赋值。数组的类型声明在[]中表示,如果事先没有声明,那默认的类型是Any类型(Any是Scala中所有类型的祖先),但是有一种情况是,如果初始化的时候所有的元素是同一种类型,那么该数组就会被认定为特定类型。比如val array = Array(1,2,3), 那么array就是Array[Int]类型, 如果val array = Array(1,2,”3”) 那么array就是Array[Any]类型。

  val arrays = new Array[String](3)
  arrays(0) = "a"
  arrays(1) = "b"
  arrays(2) = "c"

  val array = Array[String]("hello","world","!\n")
  for(str <- array)print(str)
  for(i <- 0 to arrays.length - 1) print(arrays(i))

List
Array长度是固定的,但是其中元素的值可以改变。而List长度可变,元素的值不能变。从这个角度讲,List是针对函数式编程设计的,因为它的元素不可变的,体现了函数式不产生副作用特性。List最常用的操作符是“::”,这个符号的作用是在给定List的前面添加新的元素

scala> val numbers = List(1, 2, 3, 4)
numbers: List[Int] = List(1, 2, 3, 4)

scala> 0::numbers
res14: List[Int] = List(0, 1, 2, 3, 4)

List的使用频率非常高,有很多api需要熟悉,在后面的章节会专门学习List和Map常用的api用法。

Tuple
和List一样,元组Tuple也是不可变的。但是可以将不同类型的元素组合起来。要调用特定index的元素,可以用”._”

scala> val tu = (1,2,"hello")
tu: (Int, Int, String) = (1,2,hello)

scala> tu._1
res18: Int = 1

scala> tu._2
res19: Int = 2

scala> tu._3
res20: String = hello

在创建两个元素的元组时,可以使用特殊语法:->

scala> 1 -> 2
res0: (Int, Int) = (1,2)

Set和Map

Set是不包含重复元素的集合,分为两种,一种是可变的,还有一种是不可变的。scala.collection.Set是抽象类,它提供了两个子类,scala.collection.immutable.Set和scala.collection.mutable.Set,这两个类都属于特质trait(类似于Java的接口,后面章节会提到)。默认是不可变的,即元素的值不能变。如果要用到可变Set,必须显式import scala.collection.mutable.Set.

scala> Set(1, 1, 2)
res0: scala.collection.immutable.Set[Int] = Set(1, 2)

scala> import scala.collection.mutable.Set
import scala.collection.mutable.Set

scala> val s = Set(1,2)
s: scala.collection.mutable.Set[Int] = Set(1, 2)

scala> s += 3
res21: s.type = Set(1, 2, 3)

Map是映射集,其实可以看作是元素是tuple的Set,在大数据处理中非常常见。和Set类似,也分为两种,可变和不可变。映射的值可以是任何对象。


scala> val m = Map(1->"hello", 2->2, 3->func)
m: scala.collection.immutable.Map[Int,Any] = Map(1 -> hello, 2 -> 2, 3 -> HeScaa)

scala> m(1)
res23: Any = hello

scala> m(3)
res24: Any = HeScaa

我们看到,映射的值甚至可以是函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值