Scala函数到Java函数的隐式转换
我想创建一个从Scala函数(可能是匿名函数)到Scala函数到Java函数的隐式转换,java,scala,implicit-conversion,type-inference,Java,Scala,Implicit Conversion,Type Inference,我想创建一个从Scala函数(可能是匿名函数)到java.util.function.function的隐式转换。以下是我所拥有的: import java.util.function.{Function => JavaFunction} implicit def scalaFunctionToJavaFunction[From, To](function: (From) => To): JavaFunction[From, To] = { new java.util.funct
java.util.function.function
的隐式转换。以下是我所拥有的:
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)
}
}
它可以正常工作,但当转换的函数未显式指定参数类型时,类型推断失败:
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编译器不能在第三种情况下推断参数的类型
- 我可以修改隐式转换以便推断类型吗
JavaFunction
,行为将保持不变
为什么Scala编译器不能在第三种情况下推断参数的类型
要推断lambda表达式的参数类型,所需类型必须是String=>?
(对于这种情况)。在converted3
中,预期的类型是JavaFunction[String,Int]
。这不是Scala函数,因此无法工作。它将在Scala 2.12或2.11中使用。这是根据:
如果匿名函数的预期类型为scala.function n[S1,…,Sn,R]形状,或者可以SAM转换为此类函数类型,则类型
钛
参数的定义
席
可以省略,只要
硅
在预期类型中定义,并且
钛
=
硅
这是假定的。此外,类型检查时的预期类型
E
是
R
如果函数文本没有预期类型,则必须显式指定所有形式参数类型Ti,并且预期类型e未定义
“SAM转换”部件是由-Xexperimental
/2.12激活的部件,默认情况下在2.11中无效
我可以修改隐式转换以便推断类型吗
我不这么认为。您可以做的是更改转换发生的位置:写入
val unconferted:String=>Int=s=>s.toInt
(或者只是val unconferted=(s:String=>s.toInt
)并将其传递到需要JavaFunction[String,Int]
的位置 当您编写val foo:SomeType=bar
时,编译器正在寻找一种“证明”赋值有效的方法。这可以通过两种方式之一来证明:要么是bar
有一个类型,即SomeType
的子类(或者显然是SomeType
本身),要么是从任何类型bar
到SomeType
的隐式转换。
正如yoy所看到的,在这两种情况下,必须知道bar
的类型。但是当您编写val converted3:JavaFunction[String,Int]=s=>s.toInt
时,右侧的类型没有定义。编译器知道,这是一个返回Int的函数,但如果没有参数类型,这是不够的
另一种说法是编译器不会检查作用域中的每个隐式转换,返回与LHS兼容的内容,为了使用转换,它需要知道输入类型
没有办法解决这个问题,您必须以某种方式定义rhs的类型,以便能够使用隐式转换。谢谢您的回复。请您提供一些参考,说明为什么预期的类型必须是
String=>?
?谢谢,这正是我要找的。另一条重要信息在中。如果我理解正确,隐式转换规则要求已知转换值的类型。是的,但它不适用于这种情况,因为在考虑任何隐式转换之前,我引用的部分已经不允许省略参数类型。谢谢您的回答。我不完全同意必须知道bar
的类型的说法。例如,在val f:Function1[String,Int]=s=>s.toInt
中,由于没有明确说明s
是String
@Mifeet,因此在这种情况下,已知RHS的类型是Function1[String,Int]
,因为不涉及隐式转换。所以,我说的是:rhs的类型必须是已知的。好吧,如果你的意思是“预期的匿名函数类型”是已知的,那么我同意。但是RHS的类型不需要是Function1[String,Int]
,它可以是,例如Function1[Object,Int]
。我知道这些都是细微的差别,抱歉唠叨:)。Function1[Object,Int]
也是Function1[String,Int]
,因为Function1在第一个参数中是逆变的。它是一个子类型。但我知道“是”这个词有时用在这个意思上,这就是所谓的“是一种关系”;)。A我找到了。它没有提供答案,但涉及到Scala函数隐式转换的相关主题。