scala – 为什么在知道类型时引用重载定义是不明确的?
发布时间:2020-12-16 10:02:32 所属栏目:安全 来源:网络整理
导读:我有这样的功能: def ifSome[B,_](pairs:(Option[B],B = _)*) { for((paramOption,setFunc) - pairs) for(someParam - paramOption) setFunc(someParam)} 和这些重载函数: class Foo{ var b="" def setB(b:String){this.b = b} def setB(b:Int){this.b = b
我有这样的功能:
def ifSome[B,_](pairs:(Option[B],B => _)*) { for((paramOption,setFunc) <- pairs) for(someParam <- paramOption) setFunc(someParam) } 和这些重载函数: class Foo{ var b="" def setB(b:String){this.b = b} def setB(b:Int){this.b = b.toString} } val f = new Foo 然后以下行产生错误: ifSome(Option("hi") -> f.setB _) <console>:11: error: ambiguous reference to overloaded definition,both method setB in class Foo of type (b: Int)Unit and method setB in class Foo of type (b: String)Unit match expected type ? ifSome(Option("hi") -> f.setB _) 但是编译器知道我们正在寻找一个Function1 [java.lang.String,_],那么为什么Function1 [Int,_]的存在会引起任何混淆呢?我错过了什么或者这是一个编译器错误(或者它应该是一个功能请求)? 我能够通过使用类似的注释来解决这个问题 ifSome(Option("hi") -> (f.setB _:String=>Unit)) 但我想明白为什么这是必要的. 解决方法
你会想尝试$scalac -Ydebug -Yinfer-debug x.scala,但首先你想要最小化.
在这种情况下,您将看到如何在curried版本中,B在第一个参数列表中得到解决: [infer method] solving for B in (bs: B*)(bfs: Function1[B,_]*)Nothing based on (String)(bfs: Function1[B,_]*)Nothing (solved: B=String) 对于未经证实的版本,你会看到一些奇怪的东西 [infer view] <empty> with pt=String => Int 因为它试图消除过载的歧义,这可能会导致你下面的奇怪解决方案. 虚拟隐式用于解决过载的唯一目的,以便推理可以继续进行.隐式本身是未使用的,仍未实现??? 这是一个非常奇怪的解决方案,但你知道重载是邪恶的,对吗?而且你必须用你可以使用的任何工具来对抗邪恶. 还要看到类型注释解决方法比仅以正常方式指定类型参数更费力. object Test extends App { def f[B](pairs: (B,B => _)*) = ??? def f2[B](bs: B*)(bfs: (B => _)*) = ??? def g(b: String) = ??? def g(b: Int) = ??? // explicitly f[String](Pair("hi",g _)) // solves for B in first ps f2("hi")(g _) // using Pair instead of arrow means less debug output //f(Pair("hi",g _)) locally { // unused,but selects g(String) and solves B=String import language.implicitConversions implicit def cnv1(v: String): Int = ??? f(Pair("hi",g _)) } // a more heavy-handed way to fix the type class P[A](a: A,fnc: A => _) class PS(a: String,fnc: String => _) extends P[String](a,fnc) def p[A](ps: P[A]*) = ??? p(new PS("hi",g _)) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |