3.3 元组与多重赋值
假定有个函数要返回多个值。比如,返回一个人的名、姓和email地址。如果使用Java的话,一种方式是返回一个PersonInfo
类的实例,其中包括与那些数据对应的字段。另一种方式是返回一个包含这些值的String[]
或ArrayList
,然后对结果进行循环,取出这些值。Scala提供了一种更简单的方式做这件事:元组和多重赋值。
元组是一个不变的对象序列,可以用逗号分隔的值进行创建。比如,下面表示一个有3个对象的元组:("Venkat", "Subramaniam", "venkats@agiledeveloper.com")
。
元组元素可以同时赋给多个var
或val
,如下面这个例子所示:
ScalaForTheJavaEyes/MultipleAssignment.scala
def getPersonInfo(primaryKey : Int) = {
// 假设用primaryKey获取一个人的信息
// 这里的返回值被硬编码了。
("Venkat", "Subramaniam", "venkats@agiledeveloper.com")
}
val (firstName, lastName, emailAddress) = getPersonInfo(1)
println("First Name is " + firstName)
println("Last Name is " + lastName)
println("Email Address is " + emailAddress)
执行这段代码的输出如下:
First Name is Venkat
Last Name is Subramaniam
Email Address is venkats@agiledeveloper.com
如果尝试将方法结果赋给数量不一致的变量会怎么样呢?Scala会密切地关注你,一旦这种情况发生,它就会报错。如果是编译代码,而不是作为脚本执行,Scala在编译时就会提示错误。比如,下面这个例子,将方法调用的结果赋值给数量少于元组个数的变量。
ScalaForTheJavaEyes/MultipleAssignment2.scala
def getPersonInfo(primaryKey : Int) = {
("Venkat", "Subramaniam", "venkats@agiledeveloper.com")
}
val (firstName, lastName) = getPersonInfo(1)
Scala会报告这样的错误:
(fragment of MultipleAssignment2.scala):5: error:
constructor cannot be instantiated to expected type;
found : (T1, T2)
required: (java.lang.String, java.lang.String, java.lang.String)
val (firstName, lastName) = getPersonInfo(1)
^
...
就算不赋值,也可以访问元组里的单个元素。比如,如果执行了val info = getPer-sonInfo(1)
,就可以用这样的语法info._1
,访问第一个元素,第二个用info._2
,以此类推。
元组不仅仅对多重赋值中有用。在并发编程里,使用元组可以把一组数据值作为消息在Actor之间传递(它们不变的属性刚好在这里派得上用场)。如此简洁的语法会让消息发送端的代码极为精炼。在接收端,使用模式匹配会让接收和处理消息变得简单,在9.3节“匹配元组和list”中会详细介绍。