2015-02-24 83 views
2

以此为后续this SO questionTuple2的概念性目的是什么?

我是新来的斯卡拉和99 problems工作。给出的解决方案是P9:

object P09 { 
    def pack[A](ls: List[A]): List[List[A]] = { 
    if (ls.isEmpty) List(List()) 
    else { 
     val (packed, next) = ls span { _ == ls.head } 
     if (next == Nil) List(packed) 
     else packed :: pack(next) 
    } 
    } 
} 

span function在这里做所有的工作。正如你从API文档中看到的那样(这是链接)span返回一个Tuple2(实际上文档说它会返回一对 - 但这已被弃用或Tuple2弃用)。我试图弄清楚为什么你不能像列表清单或其他类似的东西那样得到某种东西,并且偶然发现了上面的SO链接。据我所知,Tuple2的原因与增加性能有关,因为不必处理Java对像Integer这样的对象进行“装箱/拆箱”等操作。我的问题是

1)是一个准确的声明?

2)是否还有其他原因让类似span的东西返回Tuple2?

thx!

回答

7

相比于“标准”当A TupleN对象具有至少两个主要区别List +:

  • (同样重要的)元组的大小是预先已知的,从而允许它更好的理由(由程序员和编译器)。
  • (更重要的是)元组为其每个元素/“槽”保留类型信息

需要注意的是,如上文所提到的类型Tuple2TupleN家庭的一部分,所有使用相同的概念。例如:

scala> ("1",2,3l) 
res0: (String, Int, Long) = (1,2,3) 

scala> res0.getClass 
res1: Class[_ <: (String, Int, Long)] = class scala.Tuple3 

正如这里可以看到,每一个在3元组的元素具有不同的类型,从而允许更好的模式匹配,更严格的保护类型等

+ 异构列表是在Scala中也是可能的,但到目前为止,它们不是标准库的一部分,并且可以说难以理解,特别是对于新手来说。

+1

w00t!这有助于很多 - 吨/年! – 2015-02-24 20:13:31

+0

每个值的已知尺寸和已知类型。 – cchantep 2015-02-24 22:11:11

3

span只返回两个值。 A Tuple2可以正好保存两个值。列表可以包含任意多个值。因此,Tuple2只是比使用列表更适合。

+0

是否有一个问题,如果返回类型为List,调用者将如何实现跨度错误? – 2015-02-24 20:04:39

+0

@DavidDaedalus你是什么意思,调用者会实现'span'? 'span'已经实现,呼叫者呼叫跨度。 – sepp2k 2015-02-24 20:21:47

+0

对不起 - '来电'可能是一个糟糕的词选择。我想知道是否有一些技术优势,而不仅仅是使用列表。你的陈述是Tuple2“更适合” - 以什么方式?这不像我们运送东西,并决定是否将一双运动鞋放入鞋盒或冰箱中,对吗? – 2015-02-24 20:25:09