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。
相关文章推荐
- 求任意多边形的面积--差称法
- cmd下不能运行python解决方法
- 怎样合理地定义用户流失
- 网络协议相关
- c++ 函数库查询
- 复高斯分布证明
- linux系统初始化脚本
- JPA总结——实体关系映射(一对多@OneToMany)
- Android设计模式学习之单例模式
- HDU4387 Stone Game
- ZOJ1041 Transmitters
- Linux中fdisk命令
- C++ HOJ 猴子分桃
- canvas 基础知识整理(二)
- APNS - Apple Push Notification Service
- 移动产品经理需要跟踪app的哪些数据?
- javascript笔记05:函数表达式和函数语句的区别
- asp.net 中RadioButtonList的选项改变事件处理(采用jquery操作)
- STL算法设计理念 - 谓词,一元谓词demo
- NYOJ 46-最少乘法次数(数论)