【问题标题】:Scala Implicit class and overloading an existing functionScala 隐式类和重载现有函数
【发布时间】:2017-06-25 21:17:53
【问题描述】:

任何想法如何让以下工作:

trait HttpTransport {
  def doGet(str: String): String
}

trait CoreGet {
  def GET(str: String)(implicit imp:String): List[String]
}


trait VerbGet extends CoreGet with HttpTransport {
  override def GET(str: String)(implicit imp:String): List[String]= {
    println("->VerbGet.GET")
    val str1 = doGet(str)
    // and more biz logic calls here
    List(s"\nverb (biz logic) called url $str and got '${str1}'>")
  }
}

// PlayGet {
implicit class ExtendCoreGet(coreGet: CoreGet) {


  def GET[A](url: String)(implicit imp:String, imp2: List[A]): List[A]= {
    println(s"->ExtendCoreGet.GET($url)")

    val coreGetResult = coreGet.GET(url)
    coreGetResult.flatMap(_ => imp2)


  }
}

trait Play extends HttpTransport {
  override def doGet(str: String): String = {
    println("->Play.doGet")
    s"\nPlay.doGet($str)>"

  }
}



val client = new VerbGet with Play

client.GET("www.go.com")("hello", List("1"))  //<-- does not compile

编译器错误:

方法 GET 的参数过多 (2): (隐式 imp: 字符串)列表[字符串]

您可以在此处使用代码: https://scastie.scala-lang.org/arminio/tN9NfdxGQUmusrNL0lJ78w

【问题讨论】:

  • 方法可以通过区分第一个参数组来重载。之后就不能再做了。

标签: scala implicit


【解决方案1】:

您似乎正在尝试扩展 VerbGet 的功能。您需要解决两件事:
1.ExtendCoreGet必须扩展AnyVal才能添加更多方法。
2.您可以通过添加新方法来添加新功能,例如GET2,但您不能重载现有方法。将您的 GET 更改为 GET2 或其他有意义的东西。

ExtendCoreGet 定义应该是

implicit class ExtendCoreGet(val coreGet: CoreGet) extends AnyVal {
  def GET2[A](url: String)(implicit imp:String, imp2: List[A]): List[A]= {
    coreGet.GET(url).flatMap(_ => imp2)
  }
}

【讨论】:

  • 恐怕这个练习的全部目的是重载 GET。将其重命名为 GET2 对我不起作用。所以你是说根本不可能重载GET?
  • 普通函数应该可以(没有currying),但是currying,当你说GET(“hello”)时,不确定编译器如何决定。
  • 1.它通常会提高性能(不是很多),但“必须”是错误的。
  • 所以似乎当柯里化函数重载时,Scala 中的解析只考虑第一个参数列表:stackoverflow.com/a/7182739/317683(参见 Martin Odersky 的答案)
猜你喜欢
  • 2017-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 2021-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多