11

I was reading through coming from SQL to Slick and it states to use === instead of == for comparison.

For example,

people.filter(p => p.age >= 18 && p.name === "C. Vogt").run

What is the difference between == and ===, and why is the latter used here?

Kat
  • 4,645
  • 4
  • 29
  • 81

3 Answers3

14

== is defined on Any in Scala. Slick can't overload it for Column[...] types like it can for other operators. That's why slick needs a custom operator for equality. We chose === just like several other libraries, such as scalatest, scalaz, etc.

a == b will lead to true or false. It's a client-side comparison. a === b will lead to an object of type Column[Boolean], with an instance of Library.Equals(a,b) behind it, which Slick will compile to a server-side comparison using the SQL "a = b" (where a and b are replaced by the expressions a and b stand for).

cvogt
  • 11,260
  • 30
  • 46
13

== calls for equals, === is a custom defined method in slick which is used for column comparison:

def === [P2, R](e: Column[P2])(implicit om: o#arg[B1, P2]#to[Boolean, R]) =
  om.column(Library.==, n, e.toNode)

The problem of using == for objects is this (from this question):

Default implementation of equals() class provided by java.lang.Object compares memory location and only return true if two reference variable are pointing to same memory location i.e. essentially they are same object.

What this means is that two variables must point to the same object to be equal, example:

scala> class A
defined class A

scala> new A
res0: A = A@4e931efa

scala> new A
res1: A = A@465670b4

scala> res0 == res1
res2: Boolean = false

scala> val res2 = res0
res2: A = A@4e931efa

scala> res2 == res0
res4: Boolean = true

In the first case == returns false because res0 and res1 point to two different objects, in the second case res2 is equal to res0 because they point to the same object.

In Slick columns are abstracted in objects, so having column1 == column2 is not what you are looking for, you want to check equality for the value a column hold and not if they point to the same object. Slick then probably translates that === in a value equality in the AST (Library.== is a SqlOperator("="), n is the left hand side column and e the right hand side), but Christopher can explain that better than me.

Community
  • 1
  • 1
Ende Neu
  • 15,581
  • 5
  • 57
  • 68
  • I use `=~` and `=!` in place of `===` and `!==`, as well as `|` and `&` in place of `||` and `&&`, but that's not at all following convention, just dislike noisy DSL syntax... – virtualeyes Oct 04 '14 at 19:31
  • I don't see how it answers the question about the difference between the methods - `==` vs `===`. What does `===` offer that `==` couldn't? I'd appreciate some explanation. – Jacek Laskowski Oct 05 '14 at 13:49
  • My understanding was that for Java, `==` compares references. And in Scala, typically `==` is the way to go to actually test for equality of objects. E.g., `"abc"+"d" == "abcd"` is `true` in Scala. And that the `===` in Slick does some extra error reporting in certain cases: http://stackoverflow.com/questions/10489548/what-is-the-triple-equals-operator-in-scala-koans and see http://www.scalatest.org/getting_started_with_fun_suite – Chris Prince Sep 01 '16 at 00:53
  • The main point is that while strings may be `==`-equal to each other, they are not `==`-equal to Slick's Column objects. Redefining `==` to work here is error prone, so instead Slick defines a new method. – Paŭlo Ebermann Sep 05 '17 at 08:06
-3

'==' compare value only and result in Boolean 'True' & 'False

'===' compare completely (i.e. compare value with its data types) and result in column

example

1=='1' True 1==='1' False

Community
  • 1
  • 1