重写String.toBoolean

时间:2015-11-08 00:31:48

标签: scala implicit

我尝试了this回答,但没有帮助。这是我的实施。

implicit class MyString(s: String) {
  override def toBoolean = s.trim.toLowerCase match {
    case "true" | "t" | "1" => true
    case _ => false
  }
}

我得到的错误是:

[error]  found   : s.type (with underlying type String)
[error]  required: ?{def toBoolean: ?}
[error] Note that implicit conversions are not applicable because they are ambiguous:
[error]  both method augmentString in object Predef of type (x: String)scala.collection.immutable.StringOps
[error]  and method MyString in trait ImplicitsStartingWithS of type (s: String)foo.MyString
[error]  are possible conversion functions from s.type to ?{def toBoolean: ?}
[error]           case Some(s) => s.toBoolean
[error]                           ^

我似乎无法找到代码的错误。

2 个答案:

答案 0 :(得分:1)

toBoolean不覆盖任何内容的事实外,您的实现很好。但是,正如编译器错误有用地指出的那样,您的方法名称与toBoolean中自动导入的StringOps类中的Predef方法冲突。因此,可以应用多个隐式转换,编译器无法决定使用哪个。这就是错误表明存在歧义的原因。解决方案是以不同的方式命名您的方法,因此以下内容应该有效。

implicit class MyString(s: String) {
  def toBooleanAlt = s.trim.toLowerCase match {
    case "true" | "t" | "1" => true
    case _ => false
  }
}

答案 1 :(得分:0)

首先,请注意隐式转换不能覆盖转换类型中的方法:如果存在这样的方法,编译器就不会查找隐式转换!有一个名为Scala-Virtualized的Scala派对允许这个(你定义了一个方法infix_toBoolean(x: String)),但是我建议不要使用它来进行一般用法:如果你不能没有这个功能,请检查它进行。

在这种情况下,正如@ moem的回答所说,toBoolean实际上并未定义String。作为简单地为您的toBoolean指定其他名称的替代方法,您还可以通过使用此名称定义其他名称来明确隐藏augmentStringdef augmentString = ???

class MyString(s: String) {
  def toBoolean = s.trim.toLowerCase match {
    case "true" | "t" | "1" => true
    case _ => false
  }
}

implicit def augmentString(s: String) = new MyString(s)

当然,这也会丢失此隐式提供的所有其他方法,但您可以在MyString中提供它们(例如,通过扩展StringOps)。