问题是为什么下面的代码不能用于类型推断(下面是一个REPL会话来演示),它可以修复吗?更具体地说,这与编译器用于推断返回类型的CanBuildFrom的使用有何不同?
鉴于此代码:
object S {
import java.net._
trait UrlLike[T] {
def url(s: String): T
}
object UrlLike {
implicit object str extends UrlLike[String]{def url(s: String) = s}
implicit object url extends UrlLike[URL]{def url(s: String) = new URL(s)}
implicit object uri extends UrlLike[URI]{def url(s: String) = new URI(s)}
}
trait UrlSupport {
val _url: String
def url[T : UrlLike]: T = implicitly[UrlLike[T]].url(_url)
}
}
Run Code Online (Sandbox Code Playgroud)
我在REPL(2.8.1)中有这个会话:
scala> :load c:\temp\UrlTest.scala
Loading c:\temp\UrlTest.scala...
defined module S
scala> import java.net._
import java.net._
scala> import S._
import S._
scala> new UrlSupport{val _url = "http://example.com"}
res0: java.lang.Object with S.UrlSupport = $anon$1@155bd22
scala> res0.url : String
<console>:14: error: ambiguous implicit values:
both object uri in object UrlLike of type object S.UrlLike.uri
and object url in object UrlLike of type object S.UrlLike.url
match expected type S.UrlLike[T]
res0.url : String
^
scala> res0.url : URL
<console>:14: error: ambiguous implicit values:
both object uri in object UrlLike of type object S.UrlLike.uri
and object url in object UrlLike of type object S.UrlLike.url
match expected type S.UrlLike[T]
res0.url : URL
^
scala> res0.url[String]
res3: String = http://example.com
scala> res0.url[URL]
res4: java.net.URL = http://example.com
Run Code Online (Sandbox Code Playgroud)
我可以看到为什么你希望它工作,但显然,类型推理器没有使用返回类型来推断T.我也期待它.
至于歧义,CanBuildFrom通过不在同一"级别"中定义所有内容来避免模棱两可.例如,这解决了歧义问题:
trait LowPriorityImplicits {
implicit object url extends UrlLike[URL]{def url(s: String) = new URL(s)}
implicit object uri extends UrlLike[URI]{def url(s: String) = new URI(s)}
}
object UrlLike extends LowPriorityImplicits {
implicit object str extends UrlLike[String]{def url(s: String) = s}
}
Run Code Online (Sandbox Code Playgroud)
但是,它不会使类型推断以您想要的方式工作:
scala> res0.url : URL
<console>:16: error: type mismatch;
found : String
required: java.net.URL
res0.url : URL
^
Run Code Online (Sandbox Code Playgroud)
这表明它显然在T不考虑返回类型的情况下进行推理.
| 归档时间: |
|
| 查看次数: |
1088 次 |
| 最近记录: |