Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala函数到Java函数的隐式转换_Java_Scala_Implicit Conversion_Type Inference - Fatal编程技术网

Scala函数到Java函数的隐式转换

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

我想创建一个从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.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编译器不能在第三种情况下推断参数的类型
  • 我可以修改隐式转换以便推断类型吗
我知道有一篇文章涉及到这个问题,但没有回答我的问题

顺便说一句,问题似乎与Java的互操作性无关。如果我用自定义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函数隐式转换的相关主题。