您的位置:首页 > 其它

Scala语法要点

2015-07-09 19:01 176 查看

Scala语法要点

Links

比较有用的链接收集如下。

官方的语法要点:http://docs.scala-lang.org/cheatsheets/

不错的教程:http://www.tutorialspoint.com/scala/

还可以但不太清楚:http://www.code123.cc/672.html

变量和函数的声明

Scala中比较奇怪的是变量和函数声明,譬如:

// 下面是两种变量,一种是普通变量,另外一种类似C++的引用
var v0 = 10
val v1 = 10
// 函数的声明,用的def关键字,但是也用等号
def f0(): Unit = {
println("this is a function")
}


Scala的函数返回值Unit是没有返回值的意思,参数也是类似UML格式,但是更重要的是和变量声明一样,用=来指名后面是函数体。

延迟求值

函数的参数可以延迟求值,譬如参数传进去是函数变量时,或者类型是函数变量时。

对于函数参数是变量的延迟求值,譬如:

// 延迟求值,参数可以是函数变量
def max(a: Int, b: Int): Int = {
if (a < b) return b else return a
}
println(t0(max(10, 11)))
// 下面的例子中,max会在t0中求值,而不是求值后把结果作为参数传进去,
// 也就是延迟求值,即call-by-name
def t0(v: => Int): Int = {
return v * 3;
}
// 下面的例子中,max会求值后再传给t0,即call-by-value
def t0(v: Int): Int = {
return v* 3
}


对于函数参数是函数变量时,即明确定义参数的函数原型时,譬如:

// 延迟求值,参数可以是函数变量,注意传参方式变了,三个参数了。
def max(a: Int, b: Int): Int = {
if (a < b) return b else return a
}
println(t0(max, 10, 11))
// 因为第一个参数是函数,所以必须要延迟求值,也就是必须call-by-name
// 注意使用参数v的方式也变了。
def t0(v: (Int, Int) => Int, a: Int, b: Int): Int = {
return v(a, b) * 3
}


函数参数

函数的参数只有一种形式,即
def f(v: Type): Type = {}
,也就是说,所有的参数都是
v: Type
,即名称和类型。

但是有几种不同的情况,譬如:

v: Int
,这种就是普通参数,call-by-value,预先求值的。

v: => Int
,这种就是普通参数,call-by-value,延迟求值的。可以把
=> Int
看做是类型,这种类型就说明是延迟求值。

v: (Int) => Int
,这种就是参数类型是函数,必须是call-by-value。这个时候函数的返回值肯定就是参数的值,那么它们的类型也就是一样了。可以认为原本是
v: (Int): Int => Int
(注意这样是有语法问题的),其中
(Int): Int
就是函数的类型,两个参数一样就省略返回值,简写成
v: (Int) => Int


匿名函数

匿名函数是声明函数时没有指定函数名称,譬如传递给函数时作为参数,或者赋值给变量时。

声明匿名函数的方式和函数是不一样的,不用def,不用=定义,不包含返回值,而是用=>指定body。也就是匿名函数的声明语法是特定的,不同于函数,譬如:

(x: Int) => {
// function body, param is x
}


匿名函数作为函数参数,譬如:

def t0(v: (Int, Int) => Int, a: Int, b: Int): Int = {
return v(a, b)
}
def anonyFunc(): Int = {
t0((a: Int, b: Int) => {
println("anonymous function, a=" + a + ", b=" + b)
return a+b
}, 10, 11)
}


或者作为函数变量的用法:

def anonyFunc2(): Unit = {
val f = (a: Int, b: Int) => {
println("anonymous function as variable, a+b=" + (a+b))
return a+b
}
f(10, 11)
}


因此,closure和high order function等都很好理解了。

总结

综合上面的语法原则,各种组合就很明确了。

譬如有个帖子讨论下面两个函数定义的差别:

// http://scalagroup.group.iteye.com/group/topic/26303 def test(code: => Unit){ code }
def test1(code: () => Unit){ code }


分析这个代码,test和test1都是两个函数,区别在于参数不一样。

code: => Unit
,类似于
code: Unit
即没有类型,但是
=> Unit
表明这个是call-by-name的,即延迟赋值。

code: () => Unit
,这个参数类型是函数
():Unit
,返回值和参数类型一样是Unit,也就是这个函数参数为空返回值为空。另外,因为是函数参数所以必须是call-by-name的。

再看另外一个教程的例子:

// http://www.tutorialspoint.com/scala/scala_closures.htm val multiplier = (i:Int) => i * 10


分析这个代码,这个是个变量定义,右边是个匿名函数,也就是它是这么写的:

val multiplier = (i: Int) => {
return i * 10
}


这个就比较清楚了,multipler就是个函数变量,一个整型参数,返回值推导出来也是个整型的。所以使用时应该
multiplier(10)
结果是
100
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: