对tuple进行迭代

tuple不同于普通的集合可以通过foreach形式迭代,或许tuple更像是一个轻量级的对象或者结构(struct),你必须清楚它内部有多少元素,如果不采用模式匹配的话,就是用t.1, t.2 这样类似数组索引的方式来访问里面的元素

不同长度的tuple比如Tuple2和Tuple3并没有继承一个公共的抽象父类如Tuple。不过tuple继承了Product特质,在Product里提供了一个productIterator的方法来获取迭代器,所以在需要遍历未知长度的tuple时,可以通过这个迭代器来进行:

scala> def foo(tuple:Product) = tuple.productIterator.foreach(print)
foo: (tuple: Product)Unit

scala> foo((1,2,3))
123

二元组箭头表达式背后的语法糖

二元组表达式除了标准的小括号表达方式:("a","b")
还可以有箭头表达式:"a"->"b",看看背后是怎么被翻译的:

在 Predef里定义了从类型A隐式转换到 ArrowAssoc 的方法:

@inline implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)

看看 ArrowAssoc 这个类:

final class ArrowAssoc[A](val __leftOfArrow: A) extends AnyVal {

    @inline 
    def -> [B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y)

    def →[B](y: B): Tuple2[A, B] = ->(y)
}

定义了 -> 以及Unicode字符的方法,实现上是创建了 Tuple2。

性能考量的2点:

1) ArrowAssoc是值类型,运行时虽有隐式转换,但避免了在堆上分配一个包装对象  
2) ->方法是声明为@inline的,也提升了性能

为什么scala中的tuple定义了22个(Tuple22)?

答案见: http://www.scala-lang.org/node/890

有人开玩笑的说23才对,因为有部电影的名字叫《The Number 23》
看起来,有可能是个数学问题,但还是没有彻底明白为何。或许这样的长度已经足够了。

他引用了《Prime Curios!》这本书里对22的解读:
http://primes.utm.edu/curios/page.php?short=22 Prime Curious!

不知道其它支持tuple的语言是怎么限制的。

Tuple1的存在意义?

既然无法定义一个只包含一个元素的tuple,如下:
[scala]
scala> val t1 = (“a”) //只有一个元素时小括号不被认为tuple
t1: String = a

scala> val t1 = (“a”,”B”) //至少要2个元素
t1: (String, String) = (a,B)
[/scala]

为何在scala里还有 Tuple1这样的类型? Tuple又是不可变的,没有理由可以造出一个元素为1的tuple啊

//搞错了,《快学scala》p146页:在scala中,并没有只带一个组件的元组。这句话是错误的。
可以这样产生一个Tuple1,必须用Tuple1这个case类的半生对象来创建。

[scala]
scala> val t1 = Tuple1(“A”)
t1: (String,) = (A,)
[/scala]

TupleX 是通过 extends ProductX 来实现的,每个ProductX都有个半生对象
Product类型是用于描述笛卡尔积(cartesian products )的,似乎与向量无关,就是定义了若干元素的结构。
http://stackoverflow.com/questions/7207527/does-scala-have-syntax-for-0-and-1-tuples

这里有提到Tuple1的用途(并不主流):
http://scala-programming-language.1934581.n4.nabble.com/for-x-String-lt-xs-yield-Why-Hello-There-Tuple1-td2065814.html