在Scala中是否可以将参数隐式转换为提取器(不适用)?

在Scala中是否可以将参数隐式转换为提取器(不适用)?,scala,extractor,unapply,Scala,Extractor,Unapply,我创建了一个名为CaseSensitive的类,它包装了一个字符串(请参阅) 我创建了一个case类,它的成员变量类型为CaseSensitive,因此它得到了一个默认的unapply方法,该方法提取CaseSensitive类型的变量,但我希望这样使用它: case class PropertyKey( val name : CaseInsensitive ) val foo = new PropertyKey("foo") val result = foo match { case P

我创建了一个名为CaseSensitive的类,它包装了一个字符串(请参阅)

我创建了一个case类,它的成员变量类型为CaseSensitive,因此它得到了一个默认的unapply方法,该方法提取CaseSensitive类型的变量,但我希望这样使用它:

case class PropertyKey( val name : CaseInsensitive )

val foo = new PropertyKey("foo")
val result = foo match {
  case PropertyKey("foo") => true
  case _ => false
}
此代码无法编译:(在提取器行,而不是构造函数行)

但我认为我从字符串到不区分大小写的隐式转换将使其能够编译,而不必键入更详细的内容:

case class PropertyKey( val name : CaseInsensitive )

val foo = new PropertyKey("foo")
val result = foo match {
  case PropertyKey(CaseInsensitive("foo")) => true
  case _ => false
}
以下是不区分大小写的实现:

/** 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))
  }
}

您始终可以定义一个方便的提取器并将其导入(请随意使用较短的名称):

那么,提取是:

  val foo = new PropertyKey("foo")
  val result = foo match {
    case PropertyKeyCI("foo") => true
    case _ => false
  }

(错误语义警报) 尽管请注意,对于PropertyKeyCI(“Foo”),这将匹配为false,因为您的“不区分大小写”类实际上是一个“小写”类。我这样说是因为我很难想象unapply()方法的预期行为。从您的案例类默认值中,您将返回原始(unlowercased)字符串的选项[String],该选项给出了以下非直观行为:

  // result == false !!!!
  val foo = new CaseInsensitive("Foo")
  val result = foo match {
    case CaseInsensitive("foo") => true
    case _ => false
  }
  val CaseInsensitive(s) = "aBcDeF"
  assertFalse(s == "abcdef")

啊。。。。扔掉它。只需使用DOS即可。

您始终可以定义一个方便的提取器并将其导入(请随意使用较短的名称):

那么,提取是:

  val foo = new PropertyKey("foo")
  val result = foo match {
    case PropertyKeyCI("foo") => true
    case _ => false
  }

(错误语义警报) 尽管请注意,对于PropertyKeyCI(“Foo”),这将匹配为false,因为您的“不区分大小写”类实际上是一个“小写”类。我这样说是因为我很难想象unapply()方法的预期行为。从您的案例类默认值中,您将返回原始(unlowercased)字符串的选项[String],该选项给出了以下非直观行为:

  // result == false !!!!
  val foo = new CaseInsensitive("Foo")
  val result = foo match {
    case CaseInsensitive("foo") => true
    case _ => false
  }
  val CaseInsensitive(s) = "aBcDeF"
  assertFalse(s == "abcdef")

啊。。。。扔掉它。只需使用DOS。

您就不能实现并使用CI比较吗?我认为CI字符串是一个格式错误的概念,区分大小写是操作的属性,而不是数据的属性。如果将CSstring与CIstring进行比较,会发生什么情况?这两个是关于C++的,但尤其是奥斯汀的作品中有一些相关的思想。我将对象存储在HashMap[T]和其他数据结构中,如何“实现CI比较”?无论如何,这个问题不是针对这个类的,不区分大小写,而是关于一般的Scala提取器。感谢链接到奥斯特恩的文章,只是想弄清楚如何在Scala中应用他的想法。提取器“解构”数据结构。您需要一个隐式from
不区分大小写
字符串
,该匹配才能工作。我并不认为这会奏效,只是为了纠正误解。@Daniel:我对两个方向都有一个含蓄的解释。我想这两条路都可以走,不是吗?例如,将PropertyKey解构为不区分大小写的,然后隐式地将其转换为字符串,然后将其与提供的字符串进行比较。或者,将PropertyKey解构为不区分大小写的字符串,然后将提供的字符串隐式转换为不区分大小写的字符串,然后对它们进行比较。难道不能实现并使用CI比较吗?我认为CI字符串是一个格式错误的概念,区分大小写是操作的属性,而不是数据的属性。如果将CSstring与CIstring进行比较,会发生什么情况?这两个是关于C++的,但尤其是奥斯汀的作品中有一些相关的思想。我将对象存储在HashMap[T]和其他数据结构中,如何“实现CI比较”?无论如何,这个问题不是针对这个类的,不区分大小写,而是关于一般的Scala提取器。感谢链接到奥斯特恩的文章,只是想弄清楚如何在Scala中应用他的想法。提取器“解构”数据结构。您需要一个隐式from
不区分大小写
字符串
,该匹配才能工作。我并不认为这会奏效,只是为了纠正误解。@Daniel:我对两个方向都有一个含蓄的解释。我想这两条路都可以走,不是吗?例如,将PropertyKey解构为不区分大小写的,然后隐式地将其转换为字符串,然后将其与提供的字符串进行比较。或者,将PropertyKey解构为不区分大小写,然后隐式地将提供的字符串转换为不区分大小写的字符串,然后进行比较。感谢Mitch,是的,我探索了这条路线,但没有那么好/干净。如果我能在同一个对象上有两个不适用的方法,那就太好了!你确定不区分大小写是一个小写类吗?它保留了现有的大小写,并将字符串的小写版本用于hashCode和equals。将编辑答案以澄清(带代码)。+1表示在同一对象上有多个未应用的方法。我不知道我试了多少次,编译器一直拒绝我。谢谢米奇,是的,我探索了这条路线,只是没有那么好/干净。如果我能在同一个对象上有两个不适用的方法,那就太好了!你确定不区分大小写是一个小写类吗?它保留了现有的大小写,并将字符串的小写版本用于hashCode和equals。将编辑答案以澄清(带代码)。+1表示在同一对象上有多个未应用的方法。我不知道我试了多少次,编译器一直拒绝我。