我尝试了以下方法在代码中创建选项检查样式:
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”?
答案 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
,然后添加额外的空格,以便将字符串配置选项的所有y
和n
对齐到同一列中。
我不确定这是否合理,但我编写了上述代码,以便您可以使用y
和n
选项的任何类型(不仅仅是字符串)后缀运算符。要启用新类型,您只需为该类型创建一个隐式DefaultConfigValue
,以便 no 选项可以返回。
答案 1 :(得分:1)
我强烈建议不要使用此模式,因为它违反了最少惊喜的原则。
StringOps
已在apply(n)
上定义String
以返回第N个字符,任何其他重载都会让很多人感到困惑。即使在DSL的背景下。
Option
也是一个易于理解的术语,其含义在这里超载。
最后:x
非常常用作方法的参数和模式匹配中的绑定值。在这样的广泛范围内使用它会导致大量阴影,并且可能会导致一些非常意外的错误消息。
您能否更好地了解您尝试实现的目标,以便我们能够提出更好的选择?