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

Previous

\n", "

Next

\n", "

Tour of Scala

\n", "
\n", "\n", "# Unified Types\n", "\n", "In Scala, all values have a type, including numerical values and functions. The diagram below illustrates a subset of the type hierarchy.\n", "\n", "\"Scala\n", "\n", "## Scala Type Hierarchy ##\n", "\n", "[`Any`](http://www.scala-lang.org/api/2.12.1/scala/Any.ipynb) is the supertype of all types, also called the top type. It defines certain universal methods such as `equals`, `hashCode`, and `toString`. `Any` has two direct subclasses: `AnyVal` and `AnyRef`.\n", "\n", "`AnyVal` represents value types. There are nine predefined value types and they are non-nullable: `Double`, `Float`, `Long`, `Int`, `Short`, `Byte`, `Char`, `Unit`, and `Boolean`. `Unit` is a value type which carries no meaningful information. There is exactly one instance of `Unit` which can be declared literally like so: `()`. All functions must return something so sometimes `Unit` is a useful return type.\n", "\n", "`AnyRef` represents reference types. All non-value types are defined as reference types. Every user-defined type in Scala is a subtype of `AnyRef`. If Scala is used in the context of a Java runtime environment, `AnyRef` corresponds to `java.lang.Object`.\n", "\n", "Here is an example that demonstrates that strings, integers, characters, boolean values, and functions are all objects just like every other object:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "attributes": { "classes": [ "tut" ], "id": "" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a string\n", "732\n", "c\n", "true\n", "ammonite.$sess.cmd0$Helper$$Lambda$2352/2102673157@2859fdff\n" ] }, { "data": { "text/plain": [ "\u001b[36mlist\u001b[39m: \u001b[32mList\u001b[39m[\u001b[32mAny\u001b[39m] = \u001b[33mList\u001b[39m(\n", " \u001b[32m\"a string\"\u001b[39m,\n", " \u001b[32m732\u001b[39m,\n", " \u001b[32m'c'\u001b[39m,\n", " true,\n", " ammonite.$sess.cmd0$Helper$$Lambda$2352/2102673157@2859fdff\n", ")" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val list: List[Any] = List(\n", " \"a string\",\n", " 732, // an integer\n", " 'c', // a character\n", " true, // a boolean value\n", " () => \"an anonymous function returning a string\"\n", ")\n", "\n", "list.foreach(element => println(element))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It defines a variable `list` of type `List[Any]`. The list is initialized with elements of various types, but they all are instance of `scala.Any`, so you can add them to the list.\n", "\n", "Here is the output of the program:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "a string\n", "732\n", "c\n", "true\n", "\n", "```\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Type Casting\n", "Value types can be cast in the following way:\n", "\"Scala\n", "\n", "For example:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "attributes": { "classes": [ "tut" ], "id": "" } }, "outputs": [ { "data": { "text/plain": [ "\u001b[36mx\u001b[39m: \u001b[32mLong\u001b[39m = \u001b[32m987654321L\u001b[39m\n", "\u001b[36my\u001b[39m: \u001b[32mFloat\u001b[39m = \u001b[32m9.8765434E8F\u001b[39m\n", "\u001b[36mface\u001b[39m: \u001b[32mChar\u001b[39m = \u001b[32m'\\u263a'\u001b[39m\n", "\u001b[36mnumber\u001b[39m: \u001b[32mInt\u001b[39m = \u001b[32m9786\u001b[39m" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "val x: Long = 987654321\n", "val y: Float = x // 9.8765434E8 (note that some precision is lost in this case)\n", "\n", "val face: Char = '☺'\n", "val number: Int = face // 9786" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Casting is unidirectional. This will not compile:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "attributes": { "classes": [ "tut" ], "id": "" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "cmd2.sc:3: type mismatch;\n", " found : Float\n", " required: Long\n", "val z: Long = y // Does not conform\n", " ^Compilation Failed" ] }, { "ename": "", "evalue": "", "output_type": "error", "traceback": [ "Compilation Failed" ] } ], "source": [ "val x: Long = 987654321\n", "val y: Float = x // 9.8765434E8\n", "val z: Long = y // Does not conform" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also cast a reference type to a subtype. This will be covered later in the tour.\n", "\n", "## Nothing and Null\n", "`Nothing` is a subtype of all types, also called the bottom type. There is no value that has type `Nothing`. A common use is to signal non-termination such as a thrown exception, program exit, or an infinite loop (i.e., it is the type of an expression which does not evaluate to a value, or a method that does not return normally).\n", "\n", "`Null` is a subtype of all reference types (i.e. any subtype of AnyRef). It has a single value identified by the keyword literal `null`. `Null` is provided mostly for interoperability with other JVM languages and should almost never be used in Scala code. We'll cover alternatives to `null` later in the tour.\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 }