2016-07-15 44 views
0

我想了解flatten方法有什麼樣的魔法。下面是一個示例表格this articleGenericTraversableTemplate :: flatten。它做什麼樣的魔術?

def toInt(s: String): Option[Int] = { 
    try { 
     Some(Integer.parseInt(s.trim)) 
    } catch { 
     // catch Exception to catch null 's' 
     case e: Exception => None 
    } 
} 

scala> val strings = Seq("1", "2", "foo", "3", "bar") 
strings: Seq[java.lang.String] = List(1, 2, foo, 3, bar) 

scala> strings.map(toInt) 
res0: Seq[Option[Int]] = List(Some(1), Some(2), None, Some(3), None) 

scala> val flattenResult = mapResult.flatten 
flattenResult: Seq[Int] = List(1, 2, 3) 

哇。它看起來像是一個奇蹟。 flatten方法如何知道我們不應該將None添加到結果集合中。這不是明顯的形式實現其在所有:

def flatten[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]): CC[B] = { 
    val b = genericBuilder[B] 
    for (xs <- sequential) 
     b ++= asTraversable(xs).seq 
    b.result() 
    } 

不能你解釋它的意義......我的意思是什麼呢,一般做什麼?也許它知道,None是一個monadic值並使用它的一些「monadic」方法。但這只是一個猜測。

回答

2

你看到flatten可以在包含兌換值GenTraversableOnce的集合稱爲:

def flatten[B](implicit asTraversable: A => GenTraversableOnce[B]): CC[B] 

由於Optioncompanion object存在的隱式轉換到Iterable,它應該有資格成爲flatten -ed(Iterable是亞型GenTraversableOnce)。

它轉換OptionList,它的實施是顯而易見的..

請糾正我,如果我錯了,我對Scala的集合實現太不堪重負......

+0

我唯一的改正是's/it's/its /'。另外,我不確定什麼是顯而易見的。另一個答案也顯示了代碼,這也不明顯。它一直不明顯。 –

+0

@ som-snytt,謝謝,糾正它。 –

+0

非常有趣。我無法想象這是一個隱含的轉換。 – user3663882

2

Flatten方法隱式接收一個方法,該方法能夠將A(在我們的例子中爲Option)並將其轉換爲GenTraversableOnce。申請時

def toList: List[A] = 
    if (isEmpty) List() else new ::(this.get, Nil) 

這意味着我們將得到一個空列表:

Option對象中有定義的隱式方法:

implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList 

而且toList檢查對象爲空返回一個可迭代前option2可用於None。

因此該行:

b ++= asTraversable(xs).seq 

實際上是添加一個空的序列上沒有或的一些的某些情況下,值列表,就對B點。

而這就是爲什麼你不能看到None /一些對象在你的壓平輸出,但只有一些對象的值。

+2

我會說,'和弗吉尼亞州,這就是爲什麼你看不到None.' https://en.wikipedia.org/wiki/Yes,_Virginia,_there_is_a_Santa_Claus –

相關問題