Scala 如果存在映射默认值,如何获取该值

Scala 如果存在映射默认值,如何获取该值,scala,scala-collections,Scala,Scala Collections,我想检索地图的默认值(如果存在)。以下是我尝试过的: def defaultValue[A, B](m: Map[A, B]): Option[B] = { m match { case m: Map.WithDefault[A, B] => Some(m.default(null)) case _ => None } } 这不起作用,因为null不是a的子类型。如何检索具有常量函数的映射的默认值 我尝试过的 生成类型为a的随机值?默认值是使用常量函数编码的

我想检索地图的默认值(如果存在)。以下是我尝试过的:

def defaultValue[A, B](m: Map[A, B]): Option[B] = {
  m match {
    case m: Map.WithDefault[A, B] => Some(m.default(null))
    case _ => None
  }
}
这不起作用,因为
null
不是
a
的子类型。如何检索具有常量函数的
映射的默认值

我尝试过的

生成类型为
a
的随机值?默认值是使用常量函数编码的,这就是为什么它需要一个参数,但在我的例子中,不应该使用参数。此外,当我放置类型为
Nothing
时,它在尝试返回常量值之前对参数进行求值,从而引发异常


我的问题与有关,但它们不提供直接检索默认值的方法。

我认为您可以通过在任意键上调用
\default
来实现:

val map=map(1->“a”)。带默认值(“b”)
map(1)//产生“a”
默认值(1)//产生“b”
不过这并不是很好,如果没有默认值,它将抛出异常,因此您需要将其包装在
Try
中,然后使用模式匹配来提取它

Try(map.default(1)).to选项匹配{
case Some(value)=>//使用该值做一些事情
case=>//做点别的
}

您可以添加一个下限,将方法签名重写为:

def defaultValue[A>:空一些(m.default(Null.asInstanceOf[A]))

<>这个版本不适用于<代码> a> p>您可以使用类型类模式来处理您的问题。您可以接收到错误,因为它可以是任何类型的类,如int、浮点等。但是您可以简单地克服这个限制,考虑以下内容:

trait DummyProvider[T] {
  def dummy: T
}

implicit def anyRefDummy[T >: Null] = new DummyProvider[T] {
  def dummy: T = null
}

implicit def numericDummy[T](implicit ev: Numeric[T]) = new DummyProvider[T] {
  def dummy: T = ev.zero
}
//probably needs to add instance for boolean
现在,您需要在代码中执行以下操作:

def defaultValue[A, B](m: Map[A, B])(implicit ev: DummyProvider[A]): Option[B] = {
  m match {
    case m: Map.WithDefault[A, B] => Some(m.default(ev.dummy))
    case _ => None
  }
}
这是不可能的 一般来说这是不可能的,因为默认的“值”实际上是一个函数,所以在一般情况下没有单一的默认值

以下源代码来自Scala 2.12。*

scala.collection.immutable.Map中存在以下内容:

  /** The same map with a given default function.
   *  Note: `get`, `contains`, `iterator`, `keys`, etc are not affected by `withDefault`.
   *
   *  Invoking transformer methods (e.g. `map`) will not preserve the default value.
   *
   *  @param d     the function mapping keys to values, used for non-present keys
   *  @return      a wrapper of the map with a default value
   */
def withDefault[V1 >: V](d: K => V1): immutable.Map[K, V1] = new Map.WithDefault[K, V1](this, d)
  /** An abstract shell used by { mutable, immutable }.Map but not by collection.Map
   *  because of variance issues.
   */
  abstract class WithDefault[K, +V](underlying: Map[K, V], d: K => V) extends AbstractMap[K, V] with Map[K, V] with Serializable {
    override def size               = underlying.size
    def get(key: K)                 = underlying.get(key) // removed in 2.9: orElse Some(default(key))
    def iterator                    = underlying.iterator
    override def default(key: K): V = d(key)
}
这是来自
scala.collection.Map

  /** The same map with a given default function.
   *  Note: `get`, `contains`, `iterator`, `keys`, etc are not affected by `withDefault`.
   *
   *  Invoking transformer methods (e.g. `map`) will not preserve the default value.
   *
   *  @param d     the function mapping keys to values, used for non-present keys
   *  @return      a wrapper of the map with a default value
   */
def withDefault[V1 >: V](d: K => V1): immutable.Map[K, V1] = new Map.WithDefault[K, V1](this, d)
  /** An abstract shell used by { mutable, immutable }.Map but not by collection.Map
   *  because of variance issues.
   */
  abstract class WithDefault[K, +V](underlying: Map[K, V], d: K => V) extends AbstractMap[K, V] with Map[K, V] with Serializable {
    override def size               = underlying.size
    def get(key: K)                 = underlying.get(key) // removed in 2.9: orElse Some(default(key))
    def iterator                    = underlying.iterator
    override def default(key: K): V = d(key)
}

为什么依赖具有默认值的映射?为什么不执行
map.get(key).getOrElse(myDefault)
?我正在将scala的集合转换为其他类型的集合,这些集合也可以具有默认值(但没有函数)。这就是我需要检索默认值的原因。我不需要特定键的值。没有具有默认值的映射。具有默认值的映射有一个默认函数,它可能是常量,也可能不是常量。这就是为什么
default
方法需要一个参数。如果我知道类型,这是一个很好的解决方案。但是,我正在g是泛型,我没有泛型类型
a
的值。恐怕你不能这样做。考虑到你现在没有,如果
a
至少是
AnyRef
的一个子类型,可以将null转换为实例,因为
Nothing
没有实例,我认为你做不到。这很好。那么我该如何处理这个问题呢当A可能是基元类型时,例如整数、布尔值、字符或其他任何类型?只需使用第二个版本,即
null.asInstanceOf[A]
,没有添加下限。感谢您的解释,但我更多的是寻找一种解决方法,而不是告诉您这是不可能的。请参阅公认的答案。不错,但要将隐式定义纳入范围总是很困难的。