探索Scala(6)-- Tuples

本文讨论一下Tuple的用法和实现方式

Unit

Scala语言没有void关键字,取而代之的,是Unit概念(和对象)。Scala比Java更加OO,这也算是其中一个方面。从Scala语言的角度来讲,Unit和Tuple并没有太大的联系,但是基于两点原因,我打算先讨论一下Unit:

  1. 概念相似:Tuple表示包含n(n > 0)个元素的对象,Unit表示没有对象,或不需要对象。所以Unit可以认为是Tuple的一种特殊情况,即包含0个元素的Tuple。
  2. 语法相似:可以用圆括号来创建Tuple实例,比如,val t = (1, "2", false)创建了一个三元组。一对儿空圆括号则创建Unit实例,比如val u = ()

大部分时候,Unit都只是个概念,它等价于Java的void关键字。比如下面这段Scala代码:

def unitIsVoid(x: Int, y: Int): Unit = {
    val z = x + y
}

反编译之后,实际上得到下面的Java代码:

public void unitIsVoid(int x, int y) {
    int z = x + y;
}

但如果你非要使用Unit实例的话,也是行得通的:

def unitIsNotVoid(nothing: Unit) = {
    val unit = ()
    if (unit == nothing) {
        println("unit == nothing")
    }
}

上面的Scala代码可以通过编译,但是编译器会给出一条警告:

warning: comparing values of types Unit and Unit using `==‘ will always yield true

下面是反编译之后的Java代码:

public void unitIsNotVoid(scala.runtime.BoxedUnit nothing) {
    scala.runtime.BoxedUnit unit = BoxedUnit.UNIT;
    if (unit.equals(nothing)) {
        ...
    }
}

可以看到,Unit概念的化身,就是BoxedUnit.UNIT单例对象。

Tuple1

Tuple1就是只包含一个元素的Tuple,也就是一元组。需要注意的是,Tuple1是无法用圆括号字面量来实例化的,必须用Tuple1("x")这样的方式来实例化,如下面代码所示:

def tuple1() = {
    val x = ("a")
    val y = Tuple1("b")
}

下面是反编译之后的Java代码:

String x = "a";
Tuple1 y = new Tuple1("b");

TupleN

那么可以任意表达包含n个元素的Tuple吗?答案是否定的。Scala只定义了Tuple1~Tuple22共22个Tuple(在scala包里),圆括号字面量也只支持Tuple1~Tuple22,再多就不支持了。例如下面这段代码是无法通过编译的:

def tuple23() = {
    val t23 = (1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"21","22","23")
}

Scala编译器报了下面这个错误:

error: object <none> is not a member of package scala

函数返回多个值

Tuple有很多用途。当方法想返回多个值,但又不太值得单独定义一个类的时候,就比较适合用Tuple。下面是一个例子:

def nameAndAge() = {
    ("zxh", 32)
}

把Tuple赋值给多个变量

也可以把Tuple赋值给n个变量,这相当于把Tuple给拆了,代码如下所示:

def assignToVars() = {
    val (name, age) = nameAndAge()
    println(name + " is " + age + " old")
}

实例化Map

下面这段代码实例化了一个Map:

val m = Map("a" -> 1, "b" -> 2)

看起来Scala好像支持Map字面量,但实际上并不是。下面是反编译之后的Java代码:

Tuple2[] ts = new Tuple2[2];
ts[0] = scala.Predef$ArrowAssoc$.MODULE$.$minus$greater$extension("a", 1); // ->
ts[0] = scala.Predef$ArrowAssoc$.MODULE$.$minus$greater$extension("b", 2);
scala.collection.immutable.Map$.apply(ts);

->实际上只是个隐式转换方法,下面是它的定义:

object Predef {
    implicit final class ArrowAssoc[A](private val self: A) extends AnyVal {
        @inline def -> [B](y: B): Tuple2[A, B] = Tuple2(self, y)
    }
}

也就是说,->把key和value转换成了Tuple2,然后Tuple2数组传递给了Map单例对象的apply方法。

时间: 2024-07-28 21:21:16

探索Scala(6)-- Tuples的相关文章

探索Scala(8)-- 关键字

本文比较一下Java和Scala语言的关键字 Java关键字 Java一共有50个关键字(keywords),其中有2个是保留字,目前还不曾用到:goto和const.true.false和null看起来很像关键字,但实际上只是字面量而已.本文粗略的把true.false和null也看做Java关键字,认为Java一共有53个关键字.下面是大致归类的Java关键字列表: assert boolean, byte, short, char, int, long, float, double, vo

探索Scala(4)-- Case Classes

本文简单探讨一下Scala语言Case Class的实现机制 Case Class Case Class是Scala语言模式匹配功能的基础.如果定义类的时候加上case关键字,那么它就变成了Case Class,比如下面这个简单的类CC: case class CC(x: Int, y: Int) 那么加上case关键字对于一个类来说,到底意味着什么呢?下文将进行详细的解释. 单例对象 编译CC,会产生两个class:CC.class和CC$.class.这说明,Scala会给case类自动添加

探索Scala(7)-- 字段

本文讨论一下在Scala语言里,字段(Fields)是如何实现的 字段实际上是getter/setter方法 在Scala里,字段是通过var或val关键字来定义的.var字段是可读写的,val字段是只读的.下面是一个简单的例子: class MyObj { var intVar = 1 val strVal = "str" } 反编译之后,可以得到下面的Java代码: public class MyObj { private int intVar = 1; private final

探索Scala(3)-- 单例对象

研究一下Scala语言的单例对象(Singleton Objects),为下一篇文章做准备. static不是关键字 上一篇文章提到过,interface并不是Scala语言关键字,可以自由使用.同样,static在Scala里也没有特殊的含义,也是可以自由使用的,如下面代码所示: 单例对象 Java并不是完美的面向对象语言,包括很多缺陷,比如允许static字段和方法,primitive类型,等等.Scala语言在这些方面都有所改进,所以号称是比Java更OO的语言.既然去掉了static关键

探索Scala(5)-- 基本类型

文本讨论一下Scala语言基本类型的实现方式 Java基本类型 Java的数据类型大致可以分为两类:基本(Primitive)类型和对象类型.基本类型一共有8种,分别是boolean.byte.short.char.int.long.float.double.为了把基本类型融入OO系统,Java提供了包装类(Wrapper).包装类在包java.lang里,一共8个,分别与基本类型一一对应,它们是:Boolean.Byte.Short.Character.Integer.Long.Float和D

Scala课程01

Scala课程01 简介 由于本人刚毕业,也是从事软件开发相关的工作.想再学习一下关于大数据.移动互联网.云计算相关的技术.为我的未来打好基础.并且从零开始学习大数据相关的知识,脚踏实地的走好每一步,听行业前辈说毕业生刚工作的三年是非常关键的,所有我每天抽出一点时间学习大数据相关知识, 也算是给我我未来买一份保险吧!也有从事大数据相关的工作的打算,也是未来规划的一部分吧!少年! 关于Scala介绍 Scala首先是一门编程语言,并且非常纯粹的面向对象编程语言,语法也非常简洁,相对java.Sca

[转载] 详述三种现代JVM语言--Groovy,Scala和Clojure

转载自http://www.tuicool.com/articles/jYzuAv和http://www.importnew.com/1537.html 在我与Martin Fowler曾经合作呈现的一次主题演讲中,他作出了一个有洞察性的观点: Java的遗产将是平台,而不是程序设计语言. Java技术的原始工程师们作出了一个明智的决定,就是将编程语言与运行时环境分开,最终这使得超过200种语言能够运行在Java平台上.这种架构对于该平台的长期活力是至关重要的,因为计算机程序设计语言的寿命一般都

Scala Control Structures

Scala之Control Structures 一.前言 前面学习了Scala的Numbers,接着学习Scala的Control Structures(控制结构). 二.Control Structures Scala中的控制结构与Java中的颇为类似,但也有所不同,例如,if/then/else控制结构与Java的类似,但是其可以返回值,虽然Java中有三元运算符的特殊语法,但是在Scala中使用if就可以达到同样的效果. val x = if (a) y else z 同样,Scala的

Scala学习之Tuple、Map、Array

1.Tuple Tuple的中文意思是元组,它的定义是不需要方法. 例如:val tup=(25,”Tuple”,”Map”,”Array”). 值得注意的是,Tuple在进行索引的时候,与我们平时所见到的数组是有很多不同点的,它的索引方式是通过:下划线和一个基于1的元素索引.(这里特别强调基数,因为在Java.C++中,我们定义数组的时候,都是基于0开始的) object TupleOps {   def main(args:Array[String]): Unit={     val tup