我有一段這樣的代碼:
sealed trait Json
case class JsonNumber(number: Double) extends Json
case class JsonString(text: String) extends Json
case class JsonObject(obj: Map[String, Json]) extends Json
....進而
def trimAll(json: Json): Json =
json match {
case _: JsonNumber => json
case JsonString(str) => JsonString(str.trim)
case JsonObject(obj) =>
val newObj = obj.map {
case (key, value) => (key, trimAll(value))
}
JsonObject(newObj)
}
為什么 obj.map 在這里作業?當我看到 Map.map 代碼時,它是:
def map[K2, V2](f: ((K, V)) => (K2, V2)): CC[K2, V2] = mapFactory.from(new View.Map(toIterable, f))
所以它需要一個函式,它接受輸入元組 (K,V) 并回傳另一個元組。但是在上面的代碼中,我們寧愿擁有:
{
case (key, value) => (key, trimAll(value))
}
...更令人驚訝的是,如果我這樣做:
val newObj = obj.map((k, v) => (k, trimAll(v)))
雖然這與 Map.map 的簽名完全匹配,但它給了我錯誤:
Cannot resolve overloaded method 'map'
編輯:錯誤跟蹤如下:
[error] Note: The expected type requires a one-argument function accepting a 2-Tuple.
[error] Consider a pattern matching anonymous function, `{ case (key, value) => ... }`
[error] val newObj = obj.map((key,value) => (key, trimAll(value)))
[error] ^
[error] .../JsonExercises.scala:18:37: missing parameter type
[error] val newObj = obj.map((key,value) => (key, trimAll(value)))
這雖然有效:
val newObj = obj.map(kv => (kv._1, trimAll(kv._2)))
uj5u.com熱心網友回復:
我假設您使用的是 Scala 2,因為這已在 Scala 3 中“解決”。
caseinside amap允許您簡寫模式匹配引數,從而允許您將元組分解為兩個命名變數。
讓我們仔細看看簽名 map
def map[K2, V2](f: ((K, V)) => (K2, V2)): CC[K2, V2] = ...
注意周圍的額外括號 (K, V)
所以map需要一個一元函式(一個引數的函式),它接受一個元組并回傳另一個元組。
所以當你做
obj.map((k, v) => (k, trimAll(v)))
它被解釋為一個二元函式,帶有兩個引數k并v因而無法正常作業。
現在你會認為你可以解決這個問題,
obj.map(((k, v)) => (k, trimAll(v)))
不幸的是,Scala 2 不支持這種語法。在 Scala 2 中,不能在引數中解構元組。
作為一種變通方法,map( case ...))開發了語法。
希望這能澄清它
uj5u.com熱心網友回復:
簡短版本:(k, v) => (k, trimAll(v))是一個接受兩個引數的函式,而不是一個接受單個元組引數的函式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/344788.html
標籤:斯卡拉
上一篇:案例類上的Scala斷言未知引數
