Scala语法要点

原创 2015年07月09日 19:01:24

Scala语法要点

比较有用的链接收集如下。
官方的语法要点: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,即名称和类型。
但是有几种不同的情况,譬如:

  1. v: Int,这种就是普通参数,call-by-value,预先求值的。
  2. v: => Int,这种就是普通参数,call-by-value,延迟求值的。可以把=> Int看做是类型,这种类型就说明是延迟求值。
  3. 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都是两个函数,区别在于参数不一样。

  1. code: => Unit,类似于code: Unit即没有类型,但是=> Unit表明这个是call-by-name的,即延迟赋值。
  2. 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

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

前台DB2开发语法注意要点1

  • 2013年03月08日 09:04
  • 86KB
  • 下载

微信小程序技术分析:Mustache语法要点总结

作者名字:有渔 作者的博客:http://itsart.blog.51cto.com/ 本文链接:http://wxapp.dreawer.com/portal.php?mod=v...

Fortran77语法要点.pdf.tar.gz

  • 2007年10月26日 15:21
  • 370KB
  • 下载

正则表达式语法和用法要点详解

  • 2009年03月15日 03:08
  • 366KB
  • 下载

要点Java5 基础语法

示例程序: public class MyFirstJavaProgram { public static int i =1; public static void main(Stri...

Swif语法基础 要点归纳(一)

Swif语法基础 要点归纳
  • lboboby
  • lboboby
  • 2015年07月16日 16:07
  • 601

C++ 继承(一、语法以及三种继承方式的要点)

一、语法    class 子类名: 继承方式1 基类名1,继承方式2 基类名2,...{    //子类定义;    }; 二、继承的基本要点:   1> 一个子类对象在任何时候都可以作为...
  • whh_tg
  • whh_tg
  • 2012年12月25日 12:34
  • 1053

第1章-安装Node.js及相关要点-1.2.Node.js的基础和语法

Node.js建立在Google Chrome的V8引擎和他的ECMAScript之上。 1.弱类型 2.Buffer-Node.js特殊数据类型 3.对象字面量 4.函数 ...

OC基本语法及知识要点汇总

在c语言中 我们在控制台输出信息是用printf()   Java语言则是 System.out.println() 而Objective-C  则是用 NSLog(); 1 减号(或者加号) ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Scala语法要点
举报原因:
原因补充:

(最多只允许输入30个字)