从Java 8开始,我可以通过

xyz.foreach(e -> System.out.println(e));
我可以做到以下几点
xyz.foreach(System.out::println)
我已经了解了有关方法引用如何工作的this thread,但是问题如下:

错误:(16,63)对重载定义的含糊不清的引用,
两种类型的对象IanesJsonHelper中的toJson方法(源:IanesServer)
类型(成功:布尔值)的对象IanesJsonHelper中的方法和toJson
匹配预期的类型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)
我不明白我的错误是:
  • 数组的类型为IanesServer
  • 调用方法中的
  • T应该是IanesServer(Array [IanesServer]-> Array [T]
  • 由于2。函数中的T必须与数组中的T相同,因此必须为Function [IanesServer,String]-> Function [T,String]

  • 有人可以帮我指出错误吗?目前,我非常不同意该函数是[?,String]。有任何想法吗?
    回答:
    感谢您的快速解答,这是我选择的:
     IanesJsonHelper.toJson[IanesServer](array,IanesJsonHelper.toJson)
    

    最佳答案

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

    您希望编译器推断toJson的类型为Function[IanesServer, String],因为source的类型为Array[IanerServer],因此T等于IanesServer

    不幸的是,scala编译器并不那么聪明。您可以通过两种方法在此处帮助编译器:
  • 明确说明类型
    IanesJsonHelper.toJson[IanesServer](array, IanesJsonHelper.toJson _)
  • 将参数分为两个参数列表:
    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)
    

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

    与Java或C#不同,Scala使用函数的参数列表中的所有参数来计算其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类型的参数)来推断A的类型(Option[Int]-LUB)。这就是为什么scala需要您告诉它您所指的是toJson的重载。

    另一方面,C#为wouldn't allow this

    编译错误(第17行,第3行):无法从用法中推断出方法'Program.F(T,T)'的类型参数。尝试显式指定类型参数。

    最后一点:LUBing很棒,但也提供了disadvantages

    08-07 04:22