1、if else表达式
scala中没有三目运算符,因为根本不需要。scala中if else表达式是有返回值的,如果if或者else返回的类型不一样,就返回Any类型(所有类型的公共超类型)。
例如:if else返回类型一样
var a = 20 val b = if(a>10){ 12 }else{ 30 } |
例如:if else返回类型不一样
val c = 50 val d = if(c > 20){ println("返回一个字符串") "ABC" }else{ println("helloworld") } |
如果缺少一个判断,什么都没有返回,但是Scala认为任何表达式都会有值,对于空值,使用Unit类,写做(),叫做无用占位符,相当于java中的void。
注意:行尾的位置不需要分号,只要能够从上下文判断出语句的终止即可。但是如果在单行中写多个语句,则需要分号分割。在Scala中,{}快包含一系列表达式,其结果也是一个表达式。块中最后一个表达式的值就是块的值。
2、while表达式
scala提供了类似于java的while和do循环,但是while语句的本身是没有任何返回值类型的,也就是while语句最终的返回结果是Unit类型的()。
var e = 1; val f = while(e <= 10){ e +=1 } println(e) println(f) |
scala当中while循环的contine和break:注意:scala当中并没有提供类似于java的continue和break操作,如果需要终止循环,我们可以有以下几种方式
- 使用Boolean标识来进行终端
- 使用嵌套函数,从函数中直接return
-
使用Breaks对象当中的break方法
var g = 10 val loop = new Breaks loop.breakable{ val h = while(g <=20){ g +=1 if(g == 15){ loop.break() } } println(h) }
println(g+"=============") |
3、for表达式
scala当中,为for循环这一常用的循环结构提供了很多的特性,这些特性被称之为for推导式或者for表达式
示例一:使用to实现左右两边均为闭合的访问
for(i <- 1 to 3; j <- 1 to 5){ println( i *j +" result result result result") } |
示例二:使用util实现左右两边分别为前闭后开的访问
for(i <- 1 until 5 ;j <- 2 until 5){ println(i * j ) } |
示例三:引入保护式(也称条件判断式)。我们可以在for循环条件里面加入判断表达式,如果满足则进入for循环,如果不满足则不进入for循环。类似于java当中的continue的功能类似
for(i <- 1 to 5 if i!=2){ println(i) } |
示例四:引入变量
for(i <- 1 to 3 ;j = 4-i){ println(i * j ) } |
示例五:将遍历过程中处理的结果返回到一个变量,使用yield关键字进行接收
val for5 = for(i <- 1 to 10) yield i println(for5+"for5") |
示例六:使用大括号代替小括号
for{ i <- 1 to 5 j = 5-i } println( i* j +"myij") |
4、调用函数与方法
在scala中,一般情况下我们不会刻意的去区分函数与方法的区别,但是他们确实是不同的东西。后面我们再详细探讨。首先我们要学会使用scala来调用函数与方法。
1) 调用函数,求方根
scala> import scala.math._ scala> sqrt(100) |
2) 调用方法,静态方法(scala中没有静态方法这个概念,需要通过伴生类对象来实现)
生成一个随机的素数
scala> BigInt.probablePrime(16, scala.util.Random) |
3) 调用方法,非静态方法,使用对象调用
scala> "HelloWorld".distinct |
4) apply与update方法
apply方法是调用时可以省略方法名的方法。用于构造和获取元素:
"Hello"(4) 等同于 "Hello".apply(4) Array(1,2,3) 等同于 Array.apply(1,2,3) 如: println("Hello"(4)) println("Hello".apply(4)) |
在StringOps中你会发现一个 def apply(n: Int): Char方法定义。update方法也是调用时可以省略方法名的方法,用于元素的更新:
arr(4) = 5 等同于 arr.update(4,5) 如: val arr1 = new Array[Int](5) arr1(1) = 2 arr1.update(1, 2) println(arr1.mkString(",")) |
5、scala当中的函数与方法
在scala当中,函数与方法是两个不同的概念,函数是scala当中的一等公民,scala是一门函数式的编程语言,同时兼顾了面向对象语言的特性
scala当中方法的定义
scala定义方法的标准格式为
def 方法名(参数名1: 参数类型1, 参数名2: 参数类型2) : 返回类型 = {方法体} |
示例一:定义一个最标准的方法,且定义方法的返回值类型为Int类型
def method1(num1:Int,num2:Int):Int={ num1 + num2 }
method1(1,2) |
示例二:定义一个方法,且不定义返回值
注意:如果定义的方法没有返回值,那么方法的返回值会做自动推断。根据我们方法的最后一个返回类型来推断我们的方法返回类型
def method2(num1:Int,num2:Int)={ num1 * num2 } val result = method2(2,3) println(result) |
示例三:定义一个方法,不定义返回值,可以通过自动推断,返回不同类型的值
def method3(str:String,num:Int)={ if(num>10){ num }else{ str } }
val rel1 = method3("tom",23) println(rel1) |
示例四:定义一个方法,参数给定默认值,如果不传入参数,就使用默认值来代替
def method5(num:Int=10,str:String="none")={ if(num>10){ str }else{ num } } //注意我们在调用方法的时候我们可以通过参数名来指定我们的参数的值 println(method5(str="tom")) |
示例五:变长参数,方法的参数个数不定的,类似于java当中的方法的...可变参数
def hello5(first:Int*)={ var result = 0; for(arg <- first){ result += arg } println(result) } hello5(10,20,30) hello5(10,50) |
示例六:递归函数。我们可以定义一个方法,使得方法自己调用自己,形成一个递归函数,但是方法的返回值类型必须显示的手动指定
def hello6(first:Int):Int={ if(first <= 1){ 1 }else{ first * hello6(first -1) } }
val hello6Result = hello6(10) println(hello6Result) |
示例七:定义一个方法,没有显示的指定返回值,那么我们方法当中定义的等号可以省掉
注意:如果省掉了=号,那么这个方法强调的就是一个代码执行的过程
/** * 定义了一个方法,但是方法的返回值没有显示指定, * 此时我们就可以省掉方法定义的=号,如果省掉 = 号, * 那么这个方法强调的是一个过程,代码执行的过程, * 不会产生任何的返回值 * @param first */ def hello7(first:Int){ println(first) 30 } hello7(20) |
示例八:直接通过def定义一个方法
def method01 = 12 val result = method01 println(result) |
示例九:如果方法体当中只有一行代码,我们也可以省掉大括号
def method02(num1:Int,num2:Int) = num1 + num2 val res1 = method02(12,1) println(res1) |
scala当中函数的定义
函数定义的两种形式
第一种形式:
val 函数名 = (参数名1:参数类型1,参数名2:参数类型2…) => {函数体}
第二种形式:
val 函数名 :(参数类型1,参数类型2…) => (返回类型) = {
函数体
}
示例一:定义一个标准函数,使用 =>来进行定义
var fun1 = (num1:Int,num2:Int)=>{ num1 + num2 }
fun1(1,2) |
示例二:定义匿名函数。也就是我们可以定义一个没有名字的函数
定义一个匿名函数之后,这个函数就没法使用了
(x:Int,y:String) =>{x + y}
示例三:函数定义的另外一种形式,定义一个函数,参数只有一个且是Int类型,返回值也是Int类型
val fun2 : (Int,Int)=>Int={ (num1,num2)=>num1 * num2 }
fun2(12,10) |
示例四:定义一个函数,参数值是两个,分别是Int和String,返回值是一个元组,分别是String和Int
val fun:(Int,Int)=>(Int,Int)={ (num1,num2)=>(num1+num2,num1*num2) } fun(4,8) |
scala当中函数与方法的区别以及方法转换成函数
在scala当中,函数与方法是有区别的,函数可以作为一个参数,传入到方法里面去
我们可以定义一个函数,然后再定义一个方法,但是方法的参数是一个函数
val myFunc = (x:Int) =>{ x * x } val myFunc2 :(Int) => Int ={ x => x * x }
def methodFunction(f:Int => Int):Int ={ println(f(100)) f(100) } val methodFunctionResult = methodFunction(myFunc) val methodFunctionResult2 = methodFunction(myFunc2) println(methodFunctionResult) println(methodFunctionResult2) |
val fun1:(Int,Int)=>Int={ (num1,num2)=>num1/num2 }
def method(f:(Int,Int)=>Int):Int={ f(100,10) }
method(fun1) |
方法可以自动转换成函数作为参数传递到方法里面去
def method2(x:Int) ={ x * x } def methodFunc2(x:Int => Int):Int ={ x(100) } val methodFunc2Result = methodFunc2(method2) println(methodFunc2Result) |
我们可以通过 _ 将我们的一个方法,转换成函数
def method3(x:Int,y:String ) :Int = { println(x) x } val methodToFunc = method3 _ println( methodToFunc) |
6、懒值加载
当val被声明为lazy时,他的初始化将被推迟,直到我们首次对此取值,适用于初始化开销较大的场景。
def init(): String = { println("init方法执行") "嘿嘿嘿,喵喵喵~" } lazy val msg = init() println("lazy方法没有执行") println(msg) |