[英]flatten Vs flatMap with def method and val function
使用def方法和val函數展平Vs flatMap:
我定義了一個名為toInt的def方法:
def toInt(s: String): Option[Int] = {
try {
Some(Integer.parseInt(s.trim))
} catch {
case e: Exception => None
}
}
這個方法適用於flatten和flatMap,如下所示:
//using toInt method
val x = 1.to(5).toList
val y = List("a")
val z = x ++ y
val q = z.map(_.toString)
//using map and flatten
println(q.map(toInt).flatten)
//using flatMap
println(q.flatMap(toInt))
現在我在函數“tooInt”中使用val定義了相同的toInt功能(如在def方法中):
val tooInt: String => Option[Int] = s => {
try {
Some(Integer.parseInt(s.trim))
} catch {
case c: Exception => None
}
}
如下圖所示這正常工作與扁平化,但不與flatMap:
//using map and flatten
println(q.map(tooInt).flatten)
//using flatMap // this has error
**println(q.flatMap(tooInt))**
你能幫我理解一下嗎?
最誠摯的問候,Kiran
你需要通過擴展來幫助編譯器做一些工作:
q.flatMap(s => tooInt(s))
這一切都歸結為我們在Option.scala
定義了一個隱含的option2Iterable
。 當您第一次map
然后flatten
, Option[Int]
已經在范圍內並且可以應用隱式。 但是當你使用flatMap
,編譯器必須首先將tooInt
展開為s => tooInt(s)
,然后應用隱式解析,但這不起作用。 為什么不起作用? 因為編譯器會查找隱式類型:
pt=(=> String => Option[Int]) => (String => scala.collection.GenTraversableOnce[?])
哪個不存在。 相反,首先將toInt
方法擴展為函數類型,然后在toInt
Option[Int]
搜索隱式:
-- toInt : pt=String => scala.collection.GenTraversableOnce[?] BYVALmode-EXPRmode-POLYmode (site: value r in X)
| | | | | | |-- { ((s: String) => toInt(s)) } : pt=String => scala.collection.GenTraversableOnce[?] BYVALmode-EXPRmode-POLYmode (site: value r in X)
| | | | | | | |-- ((s: String) => toInt(s)) : pt=String => scala.collection.GenTraversableOnce[?] BYVALmode-EXPRmode-POLYmode (site: value r in X)
| | | | | | | | |-- (s: String)Option[Int] : pt=scala.collection.GenTraversableOnce[?] EXPRmode (site: value $anonfun in X)
| | | | | | | | | |-- s : pt=String BYVALmode-EXPRmode (site: value $anonfun in X)
| | | | | | | | | | \-> String
| | | | | | | | | [search #3] start `(s: String)Option[Int]`, searching for adaptation to pt=Option[Int] => scala.collection.GenTraversableOnce[?] (silent: value $anonfun in X) implicits disabled
| | | | | | | | | [search #3] considering scala.this.Option.option2Iterable
我們也可以在反編譯代碼中看到它:
val r: scala.collection.immutable.IndexedSeq[Int] = q.flatMap[Int, scala.collection.immutable.IndexedSeq[Int]]({
{
final <artifact> def $anonfun$main(s: String): Iterable[Int] = scala.this.Option.option2Iterable[Int](toInt(s));
((s: String) => $anonfun$main(s))
}
}, immutable.this.IndexedSeq.canBuildFrom[Int]());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.