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

Previous

\n", "

Next

\n", "

Tour of Scala

\n", "
\n", "\n", "# Self-type\n", "Self-types are a way to declare that a trait must be mixed into another trait, even though it doesn't directly extend it. That makes the members of the dependency available without imports.\n", "\n", "A self-type is a way to narrow the type of `this` or another identifier that aliases `this`. The syntax looks like normal function syntax but means something entirely different.\n", "\n", "To use a self-type in a trait, write an identifier, the type of another trait to mix in, and a `=>` (e.g. `someIdentifier: SomeOtherTrait =>`)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "attributes": { "classes": [ "tut" ], "id": "" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "real Beyoncé: Just spilled my glass of lemonade\n" ] }, { "data": { "text/plain": [ "defined \u001b[32mtrait\u001b[39m \u001b[36mUser\u001b[39m\n", "defined \u001b[32mtrait\u001b[39m \u001b[36mTweeter\u001b[39m\n", "defined \u001b[32mclass\u001b[39m \u001b[36mVerifiedTweeter\u001b[39m\n", "\u001b[36mrealBeyoncé\u001b[39m: \u001b[32mVerifiedTweeter\u001b[39m = ammonite.$sess.cmd0$Helper$VerifiedTweeter@36bbcf25" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "trait User {\n", " def username: String\n", "}\n", "\n", "trait Tweeter {\n", " this: User => // reassign this\n", " def tweet(tweetText: String) = println(s\"$username: $tweetText\")\n", "}\n", "\n", "class VerifiedTweeter(val username_ : String) extends Tweeter with User { // We mixin User because Tweeter required it\n", "\tdef username = s\"real $username_\"\n", "}\n", "\n", "val realBeyoncé = new VerifiedTweeter(\"Beyoncé\")\n", "realBeyoncé.tweet(\"Just spilled my glass of lemonade\") // prints \"real Beyoncé: Just spilled my glass of lemonade\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Because we said `this: User =>` in `trait Tweeter`, now the variable `username` is in scope for the `tweet` method. This also means that since `VerifiedTweeter` extends `Tweeter`, it must also mix-in `User` (using `with User`).\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 }