Scala隐式转换apply方法

时间:2014-01-01 16:58:57

标签: scala apply implicit

我尝试了以下方法在代码中创建选项检查样式:

object Test {
  trait Check
  object x extends Check
  def option() = false
  def option(xx: Check) = true
  implicit class AugmentCheck(s: String) {
    def apply() = ""
    def apply(xx: Check) = s
  }
}
import Test._

val delete = option ( x )
val force  = option (   )

val res = "mystring" (   )

但我面临以下问题:

<console>:11: error: type mismatch;
 found   : String("mystring")
 required: ?{def apply: ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method augmentString in object Predef of type (x: String)scala.collection.
immutable.StringOps
 and method AugmentCheck in object Test of type (s: String)Test.AugmentCheck
 are possible conversion functions from String("mystring") to ?{def apply: ?}
           val res = "mystring" (   )
                     ^
<console>:11: error: String("mystring") does not take parameters
           val res = "mystring" (   )

这很不幸,因为即使符号名称存在歧义,函数签名也不应该有任何歧义。

如果我引入方法“apply”,当有参数时它可以正常工作,但不是没有:

           val res = "mystring" apply ( x )

           res == ""

在这种情况下如何删除关键字“apply”?

2 个答案:

答案 0 :(得分:3)

不是使用x 代表 on off 状态,而是使用y作为n

object Test {
  val y = true
  val n = false
  class DefaultConfigValue[U](val v: U)
  implicit class ConfigValue[U](v: U) {
    def y = v
    def n(implicit default: DefaultConfigValue[U]) = default.v
  }
  implicit val defaultConfigString = new DefaultConfigValue("")
}

import Test._
import language.postfixOps

val delete = y
val force  = n

val res1 = "my first string"   y
val res2 = "my second string"  n

注意如何导入postfixOps,然后添加额外的空格,以便将字符串配置选项的所有yn对齐到同一列中。

我不确定这是否合理,但我编写了上述代码,以便您可以使用yn选项的任何类型(不仅仅是字符串)后缀运算符。要启用新类型,您只需为该类型创建一个隐式DefaultConfigValue,以便 no 选项可以返回。

答案 1 :(得分:1)

我强烈建议不要使用此模式,因为它违反了最少惊喜的原则。

StringOps已在apply(n)上定义String以返回第N个字符,任何其他重载都会让很多人感到困惑。即使在DSL的背景下。

Option也是一个易于理解的术语,其含义在这里超载。

最后:x非常常用作方法的参数和模式匹配中的绑定值。在这样的广泛范围内使用它会导致大量阴影,并且可能会导致一些非常意外的错误消息。

您能否更好地了解您尝试实现的目标,以便我们能够提出更好的选择?