【发布时间】:2009-12-01 03:26:00
【问题描述】:
我创建了一个名为 CaseInsensitive 的类,它包装了一个字符串(请参阅Implementing a string class that does case insensitive comparisions in Scala)。
我创建了一个 case 类,它有一个 CaseInsensitive 类型的成员变量,所以它有一个默认的 unapply 方法,该方法提取一个 CaseInsensitive 类型的变量,但我希望像这样使用它:
case class PropertyKey( val name : CaseInsensitive )
val foo = new PropertyKey("foo")
val result = foo match {
case PropertyKey("foo") => true
case _ => false
}
此代码编译失败:(在提取器行,而不是构造器行)
type mismatch;
found : java.lang.String("foo")
required: com.acme.CaseInsensitive
但我认为我从 String 到 CaseInsensitive 的隐式转换可以编译,而不是我必须输入更详细的内容:
case class PropertyKey( val name : CaseInsensitive )
val foo = new PropertyKey("foo")
val result = foo match {
case PropertyKey(CaseInsensitive("foo")) => true
case _ => false
}
这里是CaseInsensitive的实现:
/** Used to enable us to easily index objects by string, case insensitive
*
* Note: this class preserve the case of your string!
*/
case class CaseInsensitive ( val _s : String ) extends Proxy {
require( _s != null)
val self = _s.toLowerCase
override def toString = _s
def i = this // convenience implicit conversion
}
object CaseInsensitive {
implicit def CaseInsensitive2String(c : CaseInsensitive) = if ( c == null ) null else c._s
implicit def StringToCaseInsensitive(s : String) = CaseInsensitive(s)
def fromString( s : String ) = s match {
case null => None
case _ => Some(CaseInsensitive(s))
}
}
【问题讨论】:
-
您不能只实施和使用 CI 比较吗?我相信 CI 字符串是一个格式错误的概念,区分大小写是操作的属性,而不是数据的属性。如果将 CSstring 与 CIstring 进行比较会发生什么?这两个是关于 C++ 的,但尤其是。 Austern 的文章有一些相关的想法。 gotw.ca/gotw/029.htmlafstern.org/matt/col2_new.pdf
-
我将对象存储在 HashMap[T] 和其他数据结构中,我将如何“仅实现 CI 比较”?无论如何,这个问题并不特定于此类 CaseInsensitive,而是关于一般的 Scala 提取器。
-
感谢 Austern 文章的链接,只是想弄清楚如何在 Scala 中应用他的想法。
-
提取器“解构”数据结构。您需要一个隐含的 from
CaseInsensitivetoString才能使匹配生效。并不是说我认为它会起作用,而只是为了纠正误解。 -
@Daniel:我对两个方向都有一个隐含的。我认为它可以去任何一种方式,不是吗?例如。将 PropertyKey 解构为不区分大小写,然后将其隐式转换为字符串,然后将其与提供的字符串进行比较。或者,将 PropertyKey 解构为 CaseInsensitive,然后将提供的字符串隐式转换为 CaseInsensitive,然后进行比较。