从Java 8开始,我可以传递
的内容xyz.foreach(e -> System.out.println(e));
我可以做以下
xyz.foreach(System.out::println)
我看过this thread有关方法引用如何工作的问题,但问题如下:
错误:(16,63)对重载定义的模糊引用,
对象IanesJsonHelper中的两个方法toJson类型(source:IanesServer)String
和方法toJson在对象IanesJsonHelper中的类型(success:Boolean)String
匹配预期类型函数[?,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)
我不知道我的错误是什么:
有人可以帮助指出错误吗?目前我非常不同意,该函数是[?,String]。有什么想法吗?
答案: 感谢您的快速回答,以下是我选择的内容:
IanesJsonHelper.toJson[IanesServer](array,IanesJsonHelper.toJson)
答案 0 :(得分:5)
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
超载的原因。
编译错误(第17行,第3栏):无法从用法推断出方法'Program.F(T,T)'的类型参数。尝试明确指定类型参数。
最后一点:LUBing很棒,但也提出了disadvantages。