本文介绍了从Scala函数到Java函数的隐式转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个从Scala函数(可能是匿名的)到java.util.function.Function的隐式转换.这是我所拥有的:

I would like to create an implicit conversion from a Scala function (possibly anonymous) to java.util.function.Function. Here is what I have:

import java.util.function.{Function => JavaFunction}
implicit def scalaFunctionToJavaFunction[From, To](function: (From) => To): JavaFunction[From, To] = {
  new java.util.function.Function[From, To] {
    override def apply(input: From): To = function(input)
  }
}

工作正常,除了在转换的函数未明确指定参数类型时类型推断失败:

It works fine except that the type inference fails when the function being converted doesn't specify parameter type explicitly:

val converted: JavaFunction[String, Int] = (s: String) => s.toInt // works fine
val converted2: JavaFunction[String, Int] = scalaFunctionToJavaFunction(s => s.toInt) // works
val converted3: JavaFunction[String, Int] = s => s.toInt // gives compilation error "missing parameter type"

编译器能够推断类型

我的问题是:

  • 为什么在第三种情况下Scala编译器不能推断参数的类型?
  • 我可以修改隐式转换以便推断类型吗?

我知道一个相关问题,该问题与该主题有关,但没有给出我的问题的答案

I'm aware of a related question which touches on this subject but doesn't give an answer to my questions.

问题似乎与Java的互操作性无关,顺便说一句.如果我用自定义Scala特征替换JavaFunction,其行为将保持不变.

The problem doesn't seem to be related to interoperability with Java, btw. If I replace JavaFunction with a custom Scala trait, the behavior remains the same.

推荐答案

要推断lambda表达式的参数类型,预期类型必须为String => ?(在这种情况下).在converted3中,期望的类型是JavaFunction[String, Int].这不是Scala函数,因此无法正常工作.它会在Scala 2.12或2.11中使用 -Xexperimental scalac选项 .这是根据规范 :

To infer type(s) of parameter(s) of a lambda-expression, the expected type must be String => ? (for this case). In converted3, the expected type is JavaFunction[String, Int]. This isn't a Scala function, so it won't work. It will in Scala 2.12, or in 2.11 with -Xexperimental scalac option. This is according to the specification:

如果函数文字没有期望的类型,则必须显式指定所有形式参数类型Ti,并且e的期望类型未定义.

If there is no expected type for the function literal, all formal parameter types Ti must be specified explicitly, and the expected type of e is undefined.

"SAM转换"部分是由-Xexperimental/2.12激活的部分,默认情况下在2.11中无效.

The "SAM-converted" part is the one activated by -Xexperimental/2.12 and not valid in 2.11 by default.

我不这么认为.您可以要做的就是改变发生位置转换的方式:写val unconverted: String => Int = s => s.toInt(或者只是val unconverted = (s: String) => s.toInt),然后将其传递到期望的JavaFunction[String, Int]位置.

I don't believe so. What you can do is to change the place conversion happens: write val unconverted: String => Int = s => s.toInt (or just val unconverted = (s: String) => s.toInt) and pass it where JavaFunction[String, Int] is expected.

这篇关于从Scala函数到Java函数的隐式转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 12:38