Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using implicit class to override method

My intention is to change the behaviour of the == method in String to call equalsIgnoreCase.

This code

implicit class LowerCase(s: String) {
      override def ==(that: LowerCase) = that.equalsIgnoreCase(this)
}

results in this error

error: type mismatch;
 found   : MyClass.LowerCase
 required: String
      override def ==(that: String) = that.equalsIgnoreCase(this)
like image 815
Hanxue Avatar asked Dec 20 '13 08:12

Hanxue


1 Answers

In case there is already such method in class scala compiler would not search for implicit conversion.

Note that your implementation is invalid, it should be:

implicit class LowerCase(val s: String) {
      def ==(that: LowerCase) = that.s.equalsIgnoreCase(this.s)
}

Note that it's still useless.

In case you want to use it as Map's key you should specify type manually:

implicit class LowerCase(val s: String) {
      // Use `equals`, not `==`
      override def equals(that: Any) = that match {
        case t: LowerCase => t.s.equalsIgnoreCase(this.s)
        case _ => false
      }

  override def toString() = s
}

scala> Set[LowerCase]("A", "a", "b")
res0: scala.collection.immutable.Set[LowerCase] = Set(A, b)

If you want to use this method with variables like this "a" == "A" you should use another method name:

implicit class LowerCase(val s: String) extends AnyVal {
      def ===(that: String) = s.equalsIgnoreCase(that)
}

scala> "a" === "A"
res0: Boolean = true
like image 67
senia Avatar answered Oct 19 '22 21:10

senia