gpt4 book ai didi

scala - 如何读取扩展Any但不扩展AnyRef的Scala对象的类?

转载 作者:行者123 更新时间:2023-12-04 13:17:36 24 4
gpt4 key购买 nike

我有一个异构列表,如下所示:

val l = List(1, "One", true)

我需要通过仅提取属于给定Class的对象来过滤其对象。为此,我编写了一个非常简单的方法,如下所示:
def filterByClass[A](l: List[_], c: Class[A]) =
l filter (_.asInstanceOf[AnyRef].getClass() == c)

请注意,为了避免此编译问题,我必须将显式转换添加到AnyRef中:
error: type mismatch;
found : _$1 where type _$1
required: ?{val getClass(): ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method any2stringadd in object Predef of type (x: Any)scala.runtime.StringAdd
and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A]
are possible conversion functions from _$1 to ?{val getClass(): ?}
l filter (_.getClass() == c)

但是,以这种方式调用:
filterByClass(l, classOf[String])

返回预期:
List(One)

但是当然,例如,对于Int来说,这是行不通的,因为它们扩展了Any而不是AnyRef,因此可以通过调用:
filterByClass(l, classOf[Int])

结果就是空列表。

有没有办法使我的filterByClass方法甚至与Int,Boolean以及所有其他扩展Any的类一起使用?

最佳答案

collect方法已经可以满足您的要求。例如,要收集集合中的所有Int,您可以编写

xs collect { case x: Int => x }

当然,这仅在您对类型进行硬编码时有效,但是由于对基元的处理与对引用类型的处理不同,因此这样做实际上更好。您可以使用一些类型类来使您的生活更轻松:
case class Collect[A](collect: PartialFunction[Any,A])

object Collect {

implicit val collectInt: Collect[Int] = Collect[Int]({case x: Int => x})

// repeat for other primitives

// for types that extend AnyRef
implicit def collectAnyRef[A <: AnyRef](implicit mf: ClassManifest[A]) =
Collect[A]({ case x if mf.erasure.isInstance(x) => x.asInstanceOf[A] })
}

def collectInstance[A : Collect](xs: List[_ >: A]) =
xs.collect(implicitly[Collect[A]].collect)

然后,您甚至无需传递 Class[A]实例就可以使用它:
scala> collectInstance[Int](l)
res5: List[Int] = List(1)

scala> collectInstance[String](l)
res6: List[String] = List(One)

关于scala - 如何读取扩展Any但不扩展AnyRef的Scala对象的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5611666/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com