我正在尝试编写一些字符串utils,以便能够对"myString".doSpecialConversion
形式进行隐式转换,并根据specialValue
的工作原理设置doSpecialConversion
。
尝试-1:使用特征:
trait ConversionUtils {
// Need an overridable value
lazy val specialValue = ","
implicit class StringConversions(val s: String) {
def doSpecialConversion: Option[String] = if (s == specialValue) None else Some(s)
}
}
Trait工作正常,但问题是它不是静态的,因此会创建多个StringConversions
,这是不受欢迎的。所以我尝试扩展AnyVal
,因为Another limitation that is a result of supporting only one parameter to a class is that a value class must be top-level or a member of a statically accessible object.
尝试-2:使用单身人士:
object ConversionUtils {
// Need an overridable value
lazy val specialValue = ","
implicit class StringConversions(val s: String) extends AnyVal {
def doSpecialConversion: Option[String] = if (s == specialValue) None else Some(s)
}
}
问题:我如何提供一个Util,以便能够覆盖StringConversions的specialValue并且是真正的静态?
答案 0 :(得分:1)
您可以要求隐含参数:
object ConversionUtils {
case class SpecialValue(str: String)
implicit class StringConversions(val s: String) extends AnyVal {
def doSpecialConversion(implicit sv: SpecialValue): Option[String] = if (s == sv.str) None else Some(s)
}
}
用法:
scala> implicit val sp = SpecialValue(",")
sp: ConversionUtils.SpecialValue = SpecialValue(,)
scala> "aaa".doSpecialConversion
res0: Option[String] = Some(aaa)
scala> ",".doSpecialConversion
res1: Option[String] = None
一般情况下,像machinist这样的宏库可能有助于摆脱样板。