{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "

Previous

\n", "

Next

\n", "

Tour of Scala

\n", "
\n", "\n", "# Case Classes\n", "\n", "Case classes are like regular classes with a few key differences which we will go over. Case classes are good for modeling immutable data. In the next step of the tour, we'll see how they are useful in [pattern matching](pattern-matching.ipynb).\n", "\n", "## Defining a case class\n", "A minimal case class requires the keywords `case class`, an identifier, and a parameter list (which may be empty):" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "attributes": { "classes": [ "tut" ], "id": "" } }, "outputs": [ { "data": { "text/plain": [ "defined \u001b[32mclass\u001b[39m \u001b[36mBook\u001b[39m\n", "\u001b[36mfrankenstein\u001b[39m: \u001b[32mBook\u001b[39m = \u001b[33mBook\u001b[39m(\u001b[32m\"978-0486282114\"\u001b[39m)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "case class Book(isbn: String)\n", "\n", "val frankenstein = Book(\"978-0486282114\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice how the keyword `new` was not used to instantiate the `Book` case class. This is because case classes have an `apply` method by default which takes care of object construction.\n", "\n", "When you create a case class with parameters, the parameters are public `val`s." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "attributes": { "classes": [ "tut" ], "id": "" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "cmd1.sc:5: reassignment to val\n", "val res1_3 = message1.sender = \"travis@washington.us\" // this line does not compile\n", " ^Compilation Failed" ] }, { "ename": "", "evalue": "", "output_type": "error", "traceback": [ "Compilation Failed" ] } ], "source": [ "case class Message(sender: String, recipient: String, body: String)\n", "val message1 = Message(\"guillaume@quebec.ca\", \"jorge@catalonia.es\", \"Ça va ?\")\n", "\n", "println(message1.sender) // prints guillaume@quebec.ca\n", "message1.sender = \"travis@washington.us\" // this line does not compile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can't reassign `message1.sender` because it is a `val` (i.e. immutable). It is possible to use `var`s in case classes but this is discouraged.\n", "\n", "## Comparison\n", "Case classes are compared by structure and not by reference:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "attributes": { "classes": [ "tut" ], "id": "" } }, "outputs": [ { "data": { "text/plain": [ "defined \u001b[32mclass\u001b[39m \u001b[36mMessage\u001b[39m\n", "\u001b[36mmessage2\u001b[39m: \u001b[32mMessage\u001b[39m = \u001b[33mMessage\u001b[39m(\n", " \u001b[32m\"jorge@catalonia.es\"\u001b[39m,\n", " \u001b[32m\"guillaume@quebec.ca\"\u001b[39m,\n", " \u001b[32m\"Com va?\"\u001b[39m\n", ")\n", "\u001b[36mmessage3\u001b[39m: \u001b[32mMessage\u001b[39m = \u001b[33mMessage\u001b[39m(\n", " \u001b[32m\"jorge@catalonia.es\"\u001b[39m,\n", " \u001b[32m\"guillaume@quebec.ca\"\u001b[39m,\n", " \u001b[32m\"Com va?\"\u001b[39m\n", ")\n", "\u001b[36mmessagesAreTheSame\u001b[39m: \u001b[32mBoolean\u001b[39m = true" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "case class Message(sender: String, recipient: String, body: String)\n", "\n", "val message2 = Message(\"jorge@catalonia.es\", \"guillaume@quebec.ca\", \"Com va?\")\n", "val message3 = Message(\"jorge@catalonia.es\", \"guillaume@quebec.ca\", \"Com va?\")\n", "val messagesAreTheSame = message2 == message3 // true" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Even though `message2` and `message3` refer to different objects, the value of each object is equal.\n", "\n", "## Copying\n", "You can create a (shallow) copy of an instance of a case class simply by using the `copy` method. You can optionally change the constructor arguments." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "attributes": { "classes": [ "tut" ], "id": "" } }, "outputs": [ { "data": { "text/plain": [ "defined \u001b[32mclass\u001b[39m \u001b[36mMessage\u001b[39m\n", "\u001b[36mmessage4\u001b[39m: \u001b[32mMessage\u001b[39m = \u001b[33mMessage\u001b[39m(\n", " \u001b[32m\"julien@bretagne.fr\"\u001b[39m,\n", " \u001b[32m\"travis@washington.us\"\u001b[39m,\n", " \u001b[32m\"Me zo o komz gant ma amezeg\"\u001b[39m\n", ")\n", "\u001b[36mmessage5\u001b[39m: \u001b[32mMessage\u001b[39m = \u001b[33mMessage\u001b[39m(\n", " \u001b[32m\"travis@washington.us\"\u001b[39m,\n", " \u001b[32m\"claire@bourgogne.fr\"\u001b[39m,\n", " \u001b[32m\"Me zo o komz gant ma amezeg\"\u001b[39m\n", ")\n", "\u001b[36mres2_3\u001b[39m: \u001b[32mString\u001b[39m = \u001b[32m\"travis@washington.us\"\u001b[39m\n", "\u001b[36mres2_4\u001b[39m: \u001b[32mString\u001b[39m = \u001b[32m\"claire@bourgogne.fr\"\u001b[39m\n", "\u001b[36mres2_5\u001b[39m: \u001b[32mString\u001b[39m = \u001b[32m\"Me zo o komz gant ma amezeg\"\u001b[39m" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "case class Message(sender: String, recipient: String, body: String)\n", "val message4 = Message(\"julien@bretagne.fr\", \"travis@washington.us\", \"Me zo o komz gant ma amezeg\")\n", "val message5 = message4.copy(sender = message4.recipient, recipient = \"claire@bourgogne.fr\")\n", "message5.sender // travis@washington.us\n", "message5.recipient // claire@bourgogne.fr\n", "message5.body // \"Me zo o komz gant ma amezeg\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The recipient of `message4` is used as the sender of `message5` but the `body` of `message4` was copied directly.\n", "

Previous

\n", "

Next

\n", "

Tour of Scala

\n", "
" ] } ], "metadata": { "kernelspec": { "display_name": "Scala (2.13)", "language": "scala", "name": "scala213" }, "language_info": { "codemirror_mode": "text/x-scala", "file_extension": ".scala", "mimetype": "text/x-scala", "name": "scala", "nbconvert_exporter": "script", "version": "2.13.1" } }, "nbformat": 4, "nbformat_minor": 4 }