问题描述
我想创建一个从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函数的隐式转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!