亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Scala上的類型不匹配以進行理解

Scala上的類型不匹配以進行理解

墨色風雨 2019-11-12 14:49:21
為什么這種構造會在Scala中導致類型不匹配錯誤?for (first <- Some(1); second <- List(1,2,3)) yield (first,second)<console>:6: error: type mismatch; found   : List[(Int, Int)] required: Option[?]       for (first <- Some(1); second <- List(1,2,3)) yield (first,second)如果我用列表切換Some,它可以很好地編譯:for (first <- List(1,2,3); second <- Some(1)) yield (first,second)res41: List[(Int, Int)] = List((1,1), (2,1), (3,1))這也可以正常工作:for (first <- Some(1); second <- Some(2)) yield (first,second)
查看完整描述

3 回答

?
搖曳的薔薇

TA貢獻1793條經驗 獲得超6個贊

對于理解將轉換為對mapor flatMap方法的調用。例如這個:


for(x <- List(1) ; y <- List(1,2,3)) yield (x,y)

變成:


List(1).flatMap(x => List(1,2,3).map(y => (x,y)))

因此,第一個循環值(在本例中為List(1))將接收flatMap方法調用。由于flatMap在List返回另一個List,的的理解,結果當然會是一個List。(這對我來說是新的:因為理解并不總是導致信息流,甚至不一定會導致Seqs。)


現在,看看如何flatMap在中聲明Option:


def flatMap [B] (f: (A) ? Option[B]) : Option[B]

請記住這一點。讓我們看看如何將理解錯誤(帶有的錯誤Some(1))轉換為一系列map調用:


Some(1).flatMap(x => List(1,2,3).map(y => (x, y)))

現在,很容易看到該flatMap調用的參數是按要求返回a List而不是返回的東西Option。


為了解決問題,您可以執行以下操作:


for(x <- Some(1).toSeq ; y <- List(1,2,3)) yield (x, y)

這樣編譯就可以了。值得注意的是,Option它不是Seq通常所假定的的子類型。


查看完整回答
反對 回復 2019-11-12
?
慕尼黑8549860

TA貢獻1818條經驗 獲得超11個贊

一個容易記住的技巧,因為理解會嘗試返回第一個生成器的集合類型,在這種情況下為Option [Int]。因此,如果從Some(1)開始,則應該期望Option [T]的結果。


如果要獲取列表類型的結果,則應從列表生成器開始。


為什么有此限制,而不假定您總是需要某種順序?您可能會遇到需要返回的情況Option。也許你有一個Option[Int]你想要的東西結合起來,得到一個Option[List[Int]],用下面的函數說:(i:Int) => if (i > 0) List.range(0, i) else None; 然后,您可以編寫此代碼,并在事情沒有“意義”時得到None:


val f = (i:Int) => if (i > 0) Some(List.range(0, i)) else None

for (i <- Some(5); j <- f(i)) yield j

// returns: Option[List[Int]] = Some(List(0, 1, 2, 3, 4))

for (i <- None; j <- f(i)) yield j

// returns: Option[List[Int]] = None

for (i <- Some(-3); j <- f(i)) yield j

// returns:  Option[List[Int]] = None

實際上,如何擴展理解力實際上是將類型的對象M[T]與函數組合(T) => M[U]以獲得類型的對象的相當通用的機制M[U]。在您的示例中,M可以是Option或List。通常,它必須是相同的類型M。因此,您不能將Option與List結合使用。有關可能存在的其他情況的示例M,請查看此特征的子類。


為什么結合List[T]與(T) => Option[T]工作雖然當你開始與列表?在這種情況下,庫在有意義的地方使用更通用的類型。因此,您可以將List與Traversable結合使用,并且存在從Option到Traversable的隱式轉換。


底線是:考慮要讓表達式返回哪種類型,并以該類型作為第一個生成器開始。如有必要,將其包裝為該類型。


查看完整回答
反對 回復 2019-11-12
  • 3 回答
  • 0 關注
  • 630 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號