Scala的类型检查与拉姆达抱怨,不具有明确功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala的类型检查与拉姆达抱怨,不具有明确功能相关的知识,希望对你有一定的参考价值。

我有以下Scala代码:

import java.util.{Comparator, function}

object ComparatorTest {
  Comparator.comparing[Int, String](new function.Function[Int, String] {
    override def apply(t: Int): String = t.toString
  })
}

它编译没有问题。我想我应该可以用lambda来替换Functionthat's what I understand from the doc, at least,和IntelliJ是相同的看法)。然而,当我将其替换为

  Comparator.comparing[Int, String]((t: Int) ⇒ t.toString)

我得到一个编译错误:

Error:(6, 23) overloaded method value comparing with alternatives:
  (x$1: java.util.function.Function[_ >: Int, _ <: String])java.util.Comparator[Int] <and>
  (x$1: java.util.function.Function[_ >: Int, _ <: String],x$2: java.util.Comparator[_ >: String])java.util.Comparator[Int]
 cannot be applied to (Int => String)
  Comparator.comparing[Int, String]((t: Int) ⇒ t.toString)

(它看起来对我来说,第一选择应该匹配。)

I've just asked a similar question,而解决办法是明确指定类型的参数,但是在这种情况下,我想我已经指定尽我所能。是否有另一种解决方案使用lambda,或者是一个明确的Function这里需要的?如果是后者,有解释当准确的λ可以被取代为SAM一个文档?

答案

TL; DR:使用Ordering而不是直接使用Comparator


您可以使用类型归属,迫使它认识到你的论点作为java.util.function.Function[Int, String]

Comparator.comparing[Int, String]((_.toString) : function.Function[Int, String])

需要注意的是围绕_.toString括号是必需的;否则,它会尝试向归属适用于表达在lambda而不是lambda作为一个整体。此代码基本上等同于:

val tmp: function.Function[Int, String] = _.toString
Comparator.comparing[Int, String](tmp)

然而,编写斯卡拉时,通常最好使用Ordering。由于Ordering扩展Comparator,它可以在任何地方使用Comparator预期。你可以使用它像:

val cmp: Comparator[Int] = Ordering.by(_.toString)

要么:

val cmp = Ordering.by[Int, String](_.toString)

正如你所看到的,类型推断的工作好得多这里。

另一答案

如果使用的不是Comparator Ordering原因是thenCompare,那是很容易和一个隐含的克服:

object PimpOrdering {
  implicit class OrderOrElse[T](val o: Ordering[T]) extends AnyVal {
   def orElse(o2: Ordering[T]) = new Ordering[T] {
     def compare(a: T, b: T) = {
        val cmp = o.compare(a,b)
        if (cmp == 0) o2.compare(a,b) else cmp
     }
   }
   def orElse[S : Ordering](f: T => S) = orElse(Ordering.by(f))
 }
}

现在,你可以写的东西像

Ordering.by[Foo, String](_.foo).orElse(_.bar).orElse(_.baz)

等等

以上是关于Scala的类型检查与拉姆达抱怨,不具有明确功能的主要内容,如果未能解决你的问题,请参考以下文章

波的干涉中德塔r=k倍的拉姆达的k怎么去

什么是拉姆达? [复制]

为啥 Scala 抱怨类型不匹配?

Scala编译器抱怨方法级别的泛型参数的类型不匹配

C# 拉姆达表达式相关,看一下两行代码的意思

javascript 拉姆达的东西