我正在嘗試使用foldLeftScala 中的函式從集合中洗掉具有相同欄位的類。
例如,一個Box類定義為:class Box(color: String = "", size: Int = 0)
讓我們創建一個簡單的集合Seq(Box, Box, Box)并嘗試按size欄位對其進行過濾。
val s = Seq(Box("green", 1), Box("blue", 1), Box("red", 3))
s.foldLeft(Seq(s.head)){ (boxes, nextBox) =>
if (boxes.last.size != nextBox.size) { // throws an exception
boxes : nextBox
} else {
boxes
}
}
上面的代碼拋出一個例外:value size cannot be accessed as a member of Box. 上面的代碼適用于原始型別,并且 forSeq(1, 1, 3)將產生1, 3. 如果您明確告訴編譯器(boxes: Seq[Box], nextBox: Box),它沒有幫助,即使您將回傳的值轉換為lastto也無濟于事Box。
你能解釋一下為什么嗎?
uj5u.com熱心網友回復:
上面的代碼拋出了一個例外:value size 不能作為 Box 的成員被訪問。
因為Box沒有任何稱為size; 的公共欄位。它有一個size不同的建構式引數。
您可以修復該操作class Box(color: String = "", val size: Int = 0)以使建構式引數成為欄位;或者通過使用為您(以及更多)執行此操作的案例類。
PS:它不會拋出例外,它會因編譯器錯誤而失敗;兩個非常不同的東西。
此外,您要做的只是distinctBy; 正如我常說的Scaladoc是你的朋友。
final case class Box(color: String = "", size: Int = 0)
val result = boxes.distinctBy(_.size)
由于您對這門語言似乎很陌生,并且有許多基本錯誤/誤解,我建議您選擇一些課程或閱讀有關該語言的書。另外,我鼓勵您加入Scala Discord服務器,在那里您可以提出問題并獲得更多互動式幫助。
uj5u.com熱心網友回復:
您的描述中必須缺少某些代碼,因為您不能呼叫Box(...)ifBox只是一個class. 你可以,如果它是 acase class然后 size 也可以訪問,因為案例類將它的所有建構式引數公開為成員,而標準類除非明確注釋為val:
scala> case class Box(color: String = "", size: Int = 0)
class Box
scala> val s = Seq(Box("green", 1), Box("green", 1), Box("green", 3))
val s: Seq[Box] = List(Box(green,1), Box(green,1), Box(green,3))
scala> s.foldLeft(Seq(s.head)){ (boxes, nextBox) =>
| if (boxes.last.size != nextBox.size) {
| boxes : nextBox
| } else {
| boxes
| }
| }
val res0: Seq[Box] = List(Box(green,1), Box(green,3))
或者(注意val類建構式中的 new并new實體化它們):
scala> class Box(val color: String = "", val size: Int = 0)
class Box
scala> val s = Seq(new Box("green", 1), new Box("green", 1), new Box("green", 3))
val s: Seq[Box] = List(Box@159424e2, Box@29bcf51d, Box@1e54a6b1)
scala> s.foldLeft(Seq(s.head)){ (boxes, nextBox) =>
| if (boxes.last.size != nextBox.size) {
| boxes : nextBox
| } else {
| boxes
| }
| }
val res0: Seq[Box] = List(Box@159424e2, Box@1e54a6b1)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/352949.html
標籤:斯卡拉
