gpt4 book ai didi

java - Scala 中的传递函数

转载 作者:搜寻专家 更新时间:2023-11-01 02:23:09 24 4
gpt4 key购买 nike

从 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 (Array[IanesServer] -> Array[T]
  3. 由于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] 类型,因为 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)

当您有两个参数列表时,传递给第一个列表的参数将告诉编译器如何绑定(bind) T,而编译器会将这些绑定(bind)用于其余列表。

这是另一个较短的例子:

// 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)来推断A(Option[Int] - LUB)。这就是为什么 scala 需要您告诉它您指的是 toJson 的哪个重载。

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

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.

最后一点:LUBing 很棒,但也展示了它的 disadvantages .

关于java - Scala 中的传递函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33500736/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com