I am trying to learn Scala in order to use it with Play Framework. Now I am dealing with Play for Scala + Slick for database layer and I am using a piece of code from tutorial which I do not understand and I am unable to find any info in Scala manual.
Here is the thing. I have got model named Entry. It is defined as case class and I have a companion class extended from Table.
case class Entry(id: Int, name: String)
class EntryTable(tag: Tag) extends Table[Entry](tag, "entries") {
def id = column[Int]("id", O.PrimaryKey)
def name = column[String]("name")
def * = (id, name) <> (Entry.tupled, Entry.unapply(_))
}
What I do not understand, is the last line with def *
. I know, that it has something to do with reflection. Basically I would understand the part def * = (id, name)
, but what does mean the other part. I cannot find meaning of operator <>
? Can anyone explain this to me?
Not Equal To(!=) operator checks whether the two given operands are equal or not. If not, it returns true. Otherwise it returns false. It is the exact boolean complement of the '==' operator.
In general: :: - adds an element at the beginning of a list and returns a list with the added element. ::: - concatenates two lists and returns the concatenated list.
It has no special meaning whatsoever. It is also not a well-known method name in Scala. It seems to come from some library; you need to look at the documentation of whatever library you are using to figure out what it does.
On Scala Collections there is usually :+ and +: . Both add an element to the collection. :+ appends +: prepends. A good reminder is, : is where the Collection goes. There is as well colA ++: colB to concat collections, where the : side collection determines the resulting type.
The operator <>
means a projection between the tuple (Int, String)
and case class Entry
.
It can be explained in steps:
*
projection (*
is from SELECT *
in SQL)<>
operator. It's signature, when simplified, looks like: <>[T, C](apply: T => C, unapply: C => Option[T])
(id, name)
constructs a tuple of (Int, String)
(simplified, actually it's (Rep[Int], Rep[String])
, but Slick will unlift it later)<>
maps it to Entry
, because Entry
has apply
with signature (Int, String) => Entry
, which is transformed by .tupled
to ((Int, String)) => Entry
, and unapply
with signature Entry => Option[(Int, String)]
.*
projection that can construct Entry
objects from database rows and rows from objects.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With