有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Scala中的java传递函数

由于Java 8,我可以通过

xyz.foreach(e -> System.out.println(e));

我可以做到以下几点

xyz.foreach(System.out::println)

我已经了解了this thread方法引用的工作原理,但问题如下:

Error:(16, 63) ambiguous reference to overloaded definition,

both method toJson in object IanesJsonHelper of type (source: IanesServer)String

and method toJson in object IanesJsonHelper of type (success: Boolean)String

match expected type Function[?,String]

 val json = IanesJsonHelper.toJson(array,IanesJsonHelper.toJson _)

                                                        ^

我有3个名为“toJSON”的函数

def toJson(id: Int): String

 def toJson(success: Boolean): String

 def toJson(source: IanesServer): String

最后一个是正确的

我在上面的错误消息中调用的函数是:

def toJson[T](source: Array[T], toJson: Function[T, String]): String

以下是相关代码:

 val array = new Array[IanesServer](1)
 array(0) = new IanesServer(1, "http://localhost:4567/", "Test")
 val json = IanesJsonHelper.toJson(array,IanesJsonHelper.toJson)

我不明白我的错误是什么:

  1. 该数组的类型为IanesServer
  2. 调用方法中的T应该是IanesServer(数组[IanesServer]->;数组[T]
  3. 因为2。函数中的T必须与数组中的T相同,因此必须是函数[IanesServer,String]->;函数[T,字符串]

有人能不能请麻生太郎指出错误?目前我强烈反对函数是[?,String]。有什么想法吗

答复: 感谢您的快速回答,以下是我的选择:

 IanesJsonHelper.toJson[IanesServer](array,IanesJsonHelper.toJson)

共 (1) 个答案

  1. # 1 楼答案

    def toJson[T](source: Array[T], toJson: Function[T, String]): String
    

    您希望编译器推断toJsonFunction[IanesServer, String]类型,因为sourceArray[IanerServer]类型,因此T等于IanesServer

    不幸的是,scala编译器没有那么聪明。有两种方法可以帮助编译器:

    1. 明确说明类型

      IanesJsonHelper.toJson[IanesServer](array, IanesJsonHelper.toJson _)

    2. 将参数拆分为两个参数列表:

      def toJson[T](source: Array[T])(toJson: Function[T, String]): String
      
      IanesJsonHelper.toJson(array)(IanesJsonHelper.toJson)
      

    当您有两个参数列表时,传递给第一个列表的参数将告诉编译器如何绑定T,并且编译器将对其余列表使用这些绑定

    下面是另一个较短的示例:

    // doesn't compile - the compiler doesn't realize `_` is an Int and therefore doesn't know about the `+` operator
    def map[A, B](xs: List[A], f: A => B) = ???
    map(List(1,2,3), _ + 1)  
    
    //compiles fine
    def map[A, B](xs: List[A])(f: A => B) = ???
    map(List(1,2,3))(_ + 1)
    

    这种行为可能看起来很不幸,但这是有原因的

    Scala不同于Java或C#,它使用函数参数列表中的所有参数来计算它们的LUB(最小上界),并使用它来推断函数的泛型类型参数

    例如:

    scala> def f[A](x: A, y: A): A = x
    f: [A](x: A, y: A)A
    
    scala> f(Some(1), None)
    res0: Option[Int] = Some(1)
    

    在这里,scala使用两个参数(类型Some[Int]None)来推断AOption[Int]-LUB)的类型。这就是为什么scala需要您告诉它您所指的toJson重载

    另一方面,C#

    Compilation error (line 17, col 3): The type arguments for method 'Program.F(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

    最后一个注意事项:润滑非常棒,但也有它的disadvantages