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")
}
岑忠满的博客新站点
http://cenzm.xyz