Scala函数

定义普通函数(=)(后面有不需要等号的)

参数类型必须声明,函数返回类型无需声明(只要不存在递归语句,scala会自动推导出返回值类型)
允许定义默认参数,有默认值的可不传,跟Python一个德行,包括参数调用

def helloWorld(name:String,age:Int=18) = {
	print(name,age)
}

helloWorld: (name: String, age: Int)Unit

//调用
helloWorld(age = 15)

递归函数

必须声明返回类型,因为不知道你递归到什么时候

//斐波那契数列1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144
//递归中的In = In-1 + In-2
9+8;8+7+7+6;7+6+6+5+6+5+5+4;6+5+5+4+5+4+4+3++4+3+3+2;5+4+4+3+4+3+3+2+3+2+2+1+2+1+1
 
def fab(n: Int): Int = {
  if (n < 1) {
    1
  }else{
    fab(n-1)+fab(n-2)
  }
}
print(fab(10))

变长参数

//接收到的参数为**Seq[Int] = WrappedArray(1, 23, 4, 4, 1)**
 def sum(nums:Int*) = {
	var rst = 0
	for(num <- nums){//增强for循环
		rst += rst
	}
	rst
}

传入一个已有序列

sum(1 to 5)			//错误,将一个Range赋值给Int
sum(1 to 5: _*)		//将1 to 5 这个Range解开为单个传入

与Python对比

def sum(*nums):
	rst = 0
	for num in nums:
		rst += num
	retuen rst

与java对比

int sum(int...  args){
	//todo...
}

神奇的执行逻辑(也许这就是函数式编程的冰山一角吧)

//当if...else...下方无语句时,从宏观上看,if...else...作为一个整体是** = **右边**{块表达式}**的最后一条语句,所以if...else...的返回值将作为函数的返回值
def helloWorld(name: String, age: Int) = {
  if (age >= 18) {
    printf("Hello %s you are an adult!!\n", name)
    name
  } else {
    printf("Hello %s you are a little boy!!", name)
    name
  }
}
//如下
helloWorld: (name: String, age: Int)String

//反之,就不是最后一条语句了,如果没有一个变量去接收if...else...表达式的值,if...else...的返回值就没有一点意义了
def helloWorld(name: String, age: Int) = {
  if (age >= 18) {
    printf("Hello %s you are an adult!!\n", name)
    name	//多余的表达式返回值
  } else {
    printf("Hello %s you are a little boy!!", name)
    name
  }
  val i = 1
  i
}
//如下
helloWorld: (name: String, age: Int)Int

过程(不需要返回值的函数)

没有使用等号连接{}的函数称为过程,其返回值类型为Unit,也就是没有返回值

//写法1:不写等号
def printName(name:String){
	print(name)
}
//写法2:声明无返回
def printName(name:String):Unit = {
	print(name)
}

lazy懒变量(用于耗时操作如网络,文件IO)

变量后面的表达式在定义时候不会执行任何计算,直到第一次使用,在很多时候都需要,毕竟不是所有都需要一上来就加载的,或许你可能不会有机会使用呢

import scala.io.Source._
lazy val myfile = fromFile("D:\\123.txt").mkString		//myfile: String = <lazy>
print(myfile)											//这时候才会执行计算

异常处理

使用了模式匹配的思想,catch字句里的内容跟match里的case是完全一样的。

//由于异常捕捉是按次序,如果最普遍的异常,Throwable,写在最前面,则在它后面的case都捕捉不到,因此需要将它写在最后面。
try{
  fromFile("D:\\asdasdasdasd").mkString
}catch{
  case e1:IOException => println("IO Exception")//e1是异常的名字,可以使用 _ 代替
}finally {
  println("close resource")
}
posted @ 2017-08-30 10:50  岑忠满  阅读(189)  评论(0编辑  收藏  举报