隐式 class 用于覆盖 String.toBoolean
Implicit class for overriding String.toBoolean
我尝试遵循 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] ^
我似乎找不到代码有什么问题。
除了 toBoolean
没有覆盖任何内容之外,您的实现没有问题。但是,正如编译器错误所指示的那样,您的方法名称与 Predef
中自动导入的 StringOps
class 中的 toBoolean
方法冲突。因此,可以应用的隐式转换不止一种,编译器无法决定使用哪一种。这就是错误表明存在歧义的原因。解决方案是以不同的方式命名您的方法,因此以下应该有效。
implicit class MyString(s: String) {
def toBooleanAlt = s.trim.toLowerCase match {
case "true" | "t" | "1" => true
case _ => false
}
}
首先,请注意隐式转换不能覆盖正在转换的类型中的方法:如果存在这样的方法,编译器根本不会寻找隐式!有一个名为 Scala-Virtualized 的 Scala 分支确实允许这样做(你会定义一个方法 infix_toBoolean(x: String)
),但我建议不要将其用于一般用途:如果没有此功能你就活不下去,请检查它出。
在这种情况下,正如@moem 的回答所说,toBoolean
实际上并未在 String
上定义。作为简单地为您的 toBoolean
指定不同名称的替代方法,您还可以通过使用此名称定义其他内容来在 class 中显式隐藏 augmentString
:def 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
)。
我尝试遵循 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] ^
我似乎找不到代码有什么问题。
除了 toBoolean
没有覆盖任何内容之外,您的实现没有问题。但是,正如编译器错误所指示的那样,您的方法名称与 Predef
中自动导入的 StringOps
class 中的 toBoolean
方法冲突。因此,可以应用的隐式转换不止一种,编译器无法决定使用哪一种。这就是错误表明存在歧义的原因。解决方案是以不同的方式命名您的方法,因此以下应该有效。
implicit class MyString(s: String) {
def toBooleanAlt = s.trim.toLowerCase match {
case "true" | "t" | "1" => true
case _ => false
}
}
首先,请注意隐式转换不能覆盖正在转换的类型中的方法:如果存在这样的方法,编译器根本不会寻找隐式!有一个名为 Scala-Virtualized 的 Scala 分支确实允许这样做(你会定义一个方法 infix_toBoolean(x: String)
),但我建议不要将其用于一般用途:如果没有此功能你就活不下去,请检查它出。
在这种情况下,正如@moem 的回答所说,toBoolean
实际上并未在 String
上定义。作为简单地为您的 toBoolean
指定不同名称的替代方法,您还可以通过使用此名称定义其他内容来在 class 中显式隐藏 augmentString
:def 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
)。