0514.不變元組容器-Tuples

Container - Tuples, 多元組, 組合

當需要返多重賦值例如 Strings 時, Java 的作法,
  1. 返回一個帶多 String 的實例物件
  2. 返回帶多個值的 String[] / ArrayList<String>
再迭代取出, Scala 提供更簡單的 Tuples, 一個不變的物件序列, 並用逗號加以隔開,
scala> ("a", "B", "C")
res26: (java.lang.String, java.lang.String, java.lang.String) = (a,B,C)

scala> ("a", "B", 2)  
res27: (java.lang.String, java.lang.String, Int) = (a,B,2)

scala> ("a", 2.2, 2, true)
res28: (java.lang.String, Double, Int, Boolean) = (a,2.2,2,true)

值從 1..N 計起
scala> def getInfo(x: Int) = ("Wisdom", "Fish", 22, true)
getInfo: (x: Int)(java.lang.String, java.lang.String, Int, Boolean)

scala> def getInfo(x: Int) = { ("Wisdom", "Fish", 22, true) }
getInfo: (x: Int)(java.lang.String, java.lang.String, Int, Boolean)

scala> def getInfo(x: Int) { ("Wisdom", "Fish", 22, true) }  
getInfo: (x: Int)Unit

scala> val (a, b, c, d) = getInfo(1)
a: java.lang.String = Wisdom
b: java.lang.String = Fish
c: Int = 22
d: Boolean = true

scala> var (a, b, c, d) = getInfo(1)
a: java.lang.String = Wisdom
b: java.lang.String = Fish
c: Int = 22
d: Boolean = true

未能滿足類型
scala> var (a, b, c) = getInfo(1)   
<console>:9: error: constructor cannot be instantiated to expected type;
 found   : (T1, T2, T3)
 required: (java.lang.String, java.lang.String, Int, Boolean)
       var (a, b, c) = getInfo(1)
           ^
<console>:9: error: recursive value x$1 needs type
       var (a, b, c) = getInfo(1)
            ^

存取特定值以 _N 為方式
scala> val x = getInfo(0)
x: (java.lang.String, java.lang.String, Int, Boolean) = (Wisdom,Fish,22,true)

scala> x._2
res29: java.lang.String = Fish



Scala - Tuples 特點


  1. 同 Lists 為不可變容器
  2. 不可以 new 來實例化
  3. 自行類型推斷(Type Inference)多元組容器內的元組類型
  4. 與 Lists 不同的是可包含不同類型的元素
  5. Tuples 的不變性, 使用它在 Actor 中作為訊息傳遞, 剛好是最佳
    1. 讓訊息發送端Code簡潔
    2. 讓訊息接收端使用模式匹配讓接收和處理訊息簡化
與列表一樣,元組也是不可變的,但與列表不同,元組可以包含不同類型的元素。而列表應該是List[Int]或List[String]的樣子,元組可以 同時擁有Int和String。元組很有用,比方說,如果你需要在方法裡返回多個對象。Java裡你將經常創建一個JavaBean樣子的類去裝多個返回 值,Scala裡你可以簡單地返回一個元組。而且這麼做的確簡單:實例化一個裝有一些對象的新元組,只要把這些對象放在括號裡,並用逗號分隔即可。一旦你 已經實例化了一個元組,你可以用點號,下劃線和一個基於1的元素索引訪問它。

或許想知道為什麼你不能像訪問List裡的元素那樣訪問元組的,就像pair(0)。那是因為List的apply方法始終返回同樣的類型,但是元組裡的 或許類型不同。_1可以有一個結果類型,_2是另外一個,諸如此類。這些_N數字是基於1的,而不是基於0的,因為對於擁有靜態類型元組的其他語言,如 Haskell和ML,從1開始是傳統的設定。


Wikipedia - Tuples


在 電腦科學(特別是在程式語言資料庫關係模型)中,多元組通常被定義為從欄位名到特定值的有限函數。其目的和在數學中一樣,指出特定的實體或物件包含特定的部分且(或)具有特定的性質。但是,這裏的部分通過唯一的欄位名來識別,而不是通過位置,從而得到更多使用者較直觀的表示。 

多元組的一個例子: 

( 選手 : "Harry", 成績 : 25 ) 

就是一個映射欄位名「選手」到字元串 "Harry",映射欄位名「成績」到數 25 的函數。注意,這裏各個部分的順序互不相關,所以相同的多元組也可以寫成: 

( 成績 : 25, 選手 : "Harry" ) 

在關係模型中,這樣的多元組是表示一個簡單命題的典型。這個例子的意思就是有一個選手的名字叫 "Harry",他的成績是 25。 在程式語言中,多元組被用來構建資料結構。


Besides List, one other ordered collection of object elements that's very useful in Scala is the tuple. Like Lists, tuples are immutable, but unlike Lists, tuples can contain different types of elements. Thus whereas a list might be a List[Int] or a List[String], a tuple could contain both an Int and a String at the same time. Tuples are very useful, for example, if you need to return multiple objects from a method. Whereas in Java, you would often create a JavaBean-like class to hold the multiple return values, in Scala you can simply return a tuple. And it is simple: to instantiate a new tuple that holds some objects, just place the objects in parentheses, separated by commas. Once you have a tuple instantiated, you can access its elements individually with a dot, underscore, and the one-based index of the element. For example, type the following code into a file named luftballons.scala:

val pair = (99, "Luftballons")
println(pair._1)
println(pair._2)

In the first line of this code, you create a new tuple that contains an Int with the value 99 as its first element, and a String with the value "Luftballons" as its second element. Scala infers the type of the tuple to be Tuple2[Int, String], and gives that type to the variable pair as well. In the second line, you access the _1 field, which will produce the first element, 99. The . in the second line is the same dot you'd use to access a field or invoke a method. In this case you are accessing a field named _1. If you run this script with scala luftballons.scala, you'll see:

99
Luftballons

The actual type of a tuple depends upon the number and of elements it contains and the types of those elements. Thus, the type of (99, "Luftballons") is Tuple2[Int, String]. The type of ('u', 'r', "the", 1, 4, "me") is Tuple6[Char, Char, String, Int, Int, String].



Comments