gpt4 book ai didi

generics - 在泛型方法中返回原始集合类型

转载 作者:行者123 更新时间:2023-12-02 10:14:47 27 4
gpt4 key购买 nike

假设我们想要创建一个像 minBy 这样的函数,它返回集合中同等极简主义的所有元素:

def multiMinBy[A, B: Ordering](xs: Traversable[A])(f: A => B) = {
val minVal = f(xs minBy f)
xs filter (f(_) == minVal)
}

scala> multiMinBy(List("zza","zzza","zzb","zzzb"))(_.last)
res33: Traversable[java.lang.String] = List(zza, zzza)

到目前为止,一切都很好,只是我们有一个 Traversable 返回,而不是我们最初的 List

所以我尝试将签名更改为

def multiMinBy[A, B: Ordering, C <: Traversable[A]](xs: C)(f: A => B)

希望我能得到一个 C 而不是 Traversable[A]。但是,我没有得到任何返回:

scala> multiMinBy(List("zza","zzza","zzb","zzzb"))(_.last)

<console>:9: error: inferred type arguments [Nothing,Nothing,List[java.lang.String]]
do not conform to method multiMinBy's type parameter bounds [A,B,C <: Traversable[A]]

我认为这是因为在推断 A 之前我们在参数中出现了 C?所以我翻转了参数的顺序,并添加了一个强制转换:

def multiMinBy[A, B: Ordering, C <: Traversable[A]](f: A => B)(xs: C) = {
val minVal = f(xs minBy f)
(xs filter (f(_) == minVal)).asInstanceOf[C]
}

这是可行的,只不过我们必须这样调用它:

multiMinBy((x: String) => x.last)(List("zza","zzza","zzb","zzzb"))

有没有办法保留原始语法,同时恢复正确的集合类型?

最佳答案

我认为 Miles Sabin 的解决方案太复杂了。 Scala 的集合已经具备了使其工作所需的机制,只需进行很小的更改即可:

import scala.collection.TraversableLike
def multiMinBy[A, B: Ordering, C <: Traversable[A]]
(xs: C with TraversableLike[A, C])
(f: A => B): C = {
val minVal = f(xs minBy f)
xs filter (f(_) == minVal)
}

关于generics - 在泛型方法中返回原始集合类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8235462/

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