为啥重载的scala函数需要返回类型?
Posted
技术标签:
【中文标题】为啥重载的scala函数需要返回类型?【英文标题】:Why is return type needed on overloaded scala function?为什么重载的scala函数需要返回类型? 【发布时间】:2014-04-09 05:22:51 【问题描述】: def toJson[T](obj: T) =
gson.toJson(obj)
def toJson[T](list: Seq[T]) =
toJson(seqAsJavaList(list))
这不会编译。这被记录为一项功能 (see this answer):
当一个方法被重载并且其中一个方法调用另一个方法时。调用方法需要一个返回类型注解。
问题是:为什么?
从上面的链接+同事的一些额外想法,可能的原因如下:
scala 也使用返回类型来确定重载方法。是这样吗,为什么需要它? (例如,Java 不使用返回类型) 偏函数 - 如果其中一个方法没有参数而另一个有参数,则 toJson() 可能会被视为偏函数,因此无法确定返回类型是 String 还是 Function我知道任何人都指定返回类型是最佳实践,但为什么实际上上面的 sn-p 没有编译,如果返回类型推断不够好,为什么一开始就在那里?
【问题讨论】:
你的意思是让第二个也给gson
打电话吗?正如它所写的那样,它是无限递归的。
@barnesjd : 如果 seqAsJavaList
有任何迹象,那不是 - java.util.List
不是 Seq[T]
。
哦,对了……在这种情况下,它调用了另一个函数,这是他的问题。谢谢
@TheTerribleSwiftTomato 在范围内具有隐式转换,调用可以是递归的;当您知道预期的类型时,在重载分辨率之后应用转换,即,您无法先验地(在推理之前)告诉您打算使用哪种方法。这是重载罪恶的炼狱。
@som-snytt :我知道,因此我的回答(完整披露,以防万一:只有 last 句子是添加after您的评论已发布:) )。
【参考方案1】:
可能不是主要原因,但请注意,显式参数的另一个原因如下:
当一个方法是递归的。
问题是,根据“调用”函数的返回类型,调用可以是对其同名的,也可以是对自身的调用(即递归)。
假设:
trait C
class A extends C
def a(obj: A) = 2
现在考虑:
def a[T <: C](obj: T): Int =
a(obj)
a(new A) //an Int, 2
对比:
def a[T <: C](obj: T): Any =
a(obj)
a(new A) //infinite recursion
由于推断递归函数的返回类型是有限时间不可判定的一般,推断“调用”函数的返回类型也是有限时间不可判定的一般 em>。
【讨论】:
以上是关于为啥重载的scala函数需要返回类型?的主要内容,如果未能解决你的问题,请参考以下文章