我一直在讨论从3种方法中重构公共代码的问题,makeRequest()但是我从编译器得到了模糊的隐式匹配.我不确定这是否来自隐式方法或其他问题的默认值,但我的目标是getRequest/deleteRequest/postRequest可以简单地调用makeRequest("GET")/ makeRequest("DELETE")/ makeRequest("POST") ).以前没有任何参数是隐含的,我只是试图通过使用implicits来达到目标
def makeRequest(method: String)(implicit path: String, base: String, params: Seq[(String, String)], body: Option[String], retriesLeft: Int): Future[WSResponse] = ???
def getRequest()(implicit path: String, base: String = baseUrl, params: Seq[(String, String)] = Seq(), body: Option[String] = None, retriesLeft: Int = retries): Future[WSResponse] = makeRequest("GET")
def deleteRequest()(implicit path: String, base: String = baseUrl, params: Seq[(String, String)] = Seq(), body: Option[String] = None, retriesLeft: Int = retries): Future[WSResponse] = makeRequest("GET")
def postRequest[T]()(path: String, body: T, base: String = baseUrl, params: Seq[(String, String)] = Seq(), retriesLeft: Int = retries)
(implicit wrt: play.api.http.Writeable[T], ct : play.api.http.ContentTypeOf[T]): Future[WSResponse] = makeRequest("POST")
Run Code Online (Sandbox Code Playgroud)
我得到这个和deleteRequest相同
ambiguous implicit values:
[error] both value base of type String
[error] and value path of type String
[error] match expected type String
[error] def getRequest()(implicit path: String, base: String = baseUrl, params: Seq[(String, String)] = Seq(), body: Option[String] = None, retriesLeft: Int = retries): Future[WSResponse] = makeRequest("GET")
Run Code Online (Sandbox Code Playgroud)
我认为除非你正在做一些非常时髦的DSL,否则你应该重新使用所有这些隐含的东西.
这是解决您遇到的问题的一种方法.正如您可能已经猜到的那样,对Type的隐式工作而不是名称,因此具有两个隐式具有相同类型的是No-No.
从Scala 2.10开始,Scala允许您使用AnyVal(SIP-15)"内联"类.以下是所谓的值类的示例:
case class Path(p: String) extends AnyVal
Run Code Online (Sandbox Code Playgroud)
现在,不是使用字符串来表示您的实体,而是将它们包含在这个漂亮的"包装器"类中.关于这一点很酷的是编译器将在编译期间用String替换代码中的所有Path对象.因此,就编译代码而言,您将获得与使用String时相同的性能.您可以获得很多类型安全性而无需支付运行时间罚款.
现在回到你的案例,这里是如何解决你的问题:
case class Path(s: String) extends AnyVal
case class BaseUrl(s: String) extends AnyVal
def foo(implicit a: Path, b: BaseUrl) = a.s ++ b.s
implicit val a: Path = Path("a")
implicit val b: BaseUrl = BaseUrl("b")
Run Code Online (Sandbox Code Playgroud)
以下是如何使用它:
scala> foo
res0: String = ab
Run Code Online (Sandbox Code Playgroud)