簡體   English   中英

調用toSet丟失參數類型錯誤

[英]missing parameter type error by calling toSet

為什么這段代碼不起作用:

scala> List('a', 'b', 'c').toSet.subsets.foreach(e => println(e))

<console>:8: error: missing parameter type
              List('a', 'b', 'c').toSet.subsets.foreach(e => println(e))
                                                        ^

但是當我拆分它然后它工作正常:

scala> val itr=List('a', 'b', 'c').toSet.subsets
itr: Iterator[scala.collection.immutable.Set[Char]] = non-empty iterator

scala> itr.foreach(e => println(e))
Set()
Set(a)
Set(b)
Set(c)
Set(a, b)
Set(a, c)
Set(b, c)
Set(a, b, c)

這段代碼也可以:

Set('a', 'b', 'c').subsets.foreach(e => println(e))

首先,有一個更簡單的代碼版本具有相同的問題:

List('a', 'b', 'c').toSet.foreach(e => println(e))

這也不起作用

List('a', 'b', 'c').toBuffer.foreach(e => println(e))

但是,這些工作正常:

List('a', 'b', 'c').toList.foreach(e => println(e))
List('a', 'b', 'c').toSeq.foreach(e => println(e))
List('a', 'b', 'c').toArray.foreach(e => println(e))

如果你去看一下List類文檔,你會看到有效的方法返回一些用A參數化的類型,而不起作用的方法返回用B >: A參數化的類型B >: A 問題是Scala編譯器無法確定使用哪個B 這意味着如果你告訴它類型它會工作:

List('a', 'b', 'c').toSet[Char].foreach(e => println(e))

至於為什么 toSettoBuffer有這個簽名,我不知道......

最后,不確定這是否有用,但這也有效:

// I think this works because println can take type Any
List('a', 'b', 'c').toSet.foreach(println)

更新:在更多地討論文檔后,我注意到該方法適用於所有具有協變類型參數的類型,但具有不變類型參數B >: A在返回類型中具有B >: A 有趣的是,盡管Array在Scala中是不變的,但它們提供了兩個版本的方法(一個帶有A ,一個帶有B >: A ),這就是為什么它沒有這個錯誤。

我也從未真正回答為什么將表達式分成兩行。 當你自己簡單地調用toSet時,編譯器會自動在結果Set[B]的類型中推斷AB ,除非你給它一個特定的類型來選擇。 這就是類型推斷算法的工作原理。 但是,當你在混合中拋出另一種未知類型(即你的lambda中的e的類型)時,推理算法會扼殺和死亡 - 它只能處理未知的B >: A和未知類型的e

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM