diff --git a/_ba/tour/abstract-type-members.md b/_ba/tour/abstract-type-members.md index 9e577d7cda..b7034b6922 100644 --- a/_ba/tour/abstract-type-members.md +++ b/_ba/tour/abstract-type-members.md @@ -15,7 +15,7 @@ Trejtovi i apstraktne klase mogu imati apstraktne tipove kao članove. To znači da konkretne implementacije definišu stvarni tip. Slijedi primjer: -```tut +```scala mdoc trait Buffer { type T val element: T @@ -26,7 +26,7 @@ U gornjem primjeru smo definisali apstraktni tip `T`. On se koristi za opis člana `element`. Ovaj trejt možemo naslijediti u apstraktnoj klasi i dodati gornju granicu tipa za `T` da bi ga učinili preciznijim. -```tut +```scala mdoc abstract class SeqBuffer extends Buffer { type U type T <: Seq[U] @@ -40,7 +40,7 @@ mora biti podtip `Seq[U]` za neki novi apstraktni tip `U`. Trejtovi ili [klase](classes.html) s apstraktnim tip-članovima se često koriste u kombinaciji s instanciranjem anonimnih klasa. Radi ilustracije, pogledaćemo program koji radi s sekvencijalnim baferom koji sadrži listu integera: -```tut +```scala mdoc abstract class IntSeqBuffer extends SeqBuffer { type U = Int } @@ -61,7 +61,7 @@ Metoda `newIntSeqBuf` koristi anonimnu klasu kao implementaciju `IntSeqBuf` pos Često je moguće pretvoriti apstraktni tip-član u tipski parametar klase i obrnuto. Slijedi verzija gornjeg koda koji koristi tipske parametre: -```tut +```scala mdoc:nest abstract class Buffer[+T] { val element: T } diff --git a/_ba/tour/annotations.md b/_ba/tour/annotations.md index cccac64c35..24b17a9012 100644 --- a/_ba/tour/annotations.md +++ b/_ba/tour/annotations.md @@ -30,7 +30,7 @@ Redoslijed anotacijskih klauza nije bitan. Određene anotacije će uzrokovati pad kompajliranja ako određeni uslovi nisu ispunjeni. Npr, anotacija `@tailrec` osigurava da je metoda [tail-rekurzivna](https://en.wikipedia.org/wiki/Tail_call). Tail-rekurzija može zadržati memorijske zahtjeve konstantnim. Evo kako se koristi na metodi koja izračunava faktorijel: -```tut +```scala mdoc import scala.annotation.tailrec def factorial(x: Int): Int = { diff --git a/_ba/tour/basics.md b/_ba/tour/basics.md index 6204faa74b..bff0c133c4 100644 --- a/_ba/tour/basics.md +++ b/_ba/tour/basics.md @@ -30,7 +30,7 @@ Izrazi su izjave koje imaju vrijednost. ``` Rezultate izraza možete prikazati pomoću `println`. -```tut +```scala mdoc println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! @@ -41,7 +41,7 @@ println("Hello," + " world!") // Hello, world! Rezultatima možete dodijeliti naziv pomoću ključne riječi `val`. -```tut +```scala mdoc val x = 1 + 1 println(x) // 2 ``` @@ -51,13 +51,13 @@ Referenciranje vrijednosti ne okida njeno ponovno izračunavanje. Vrijednosti se ne mogu mijenjati. -```tut:fail +```scala mdoc:fail x = 3 // Ovo se ne kompajlira. ``` Tipovi vrijednosti mogu biti (automatski) zaključeni, ali možete i eksplicitno navesti tip: -```tut +```scala mdoc:nest val x: Int = 1 + 1 ``` @@ -67,7 +67,7 @@ Primijetite da deklaracija tipa `Int` dolazi nakon identifikatora `x`. Također Varijable su kao vrijednosti, osim što ih možete promijeniti. Varijable se definišu ključnom riječju `var`. -```tut +```scala mdoc:nest var x = 1 + 1 x = 3 // Ovo se kompajlira jer je "x" deklarisano s "var" ključnom riječju. println(x * x) // 9 @@ -75,7 +75,7 @@ println(x * x) // 9 Kao i s vrijednostima, tip možete eksplicitno navesti ako želite: -```tut +```scala mdoc:nest var x: Int = 1 + 1 ``` @@ -86,7 +86,7 @@ Izraze možete kombinovati okružujući ih s `{}`. Ovo se naziva blok. Rezultat zadnjeg izraza u bloku je rezultat cijelog bloka, također. -```tut +```scala mdoc println({ val x = 1 + 1 x + 1 @@ -99,7 +99,7 @@ Funkcije su izrazi koji primaju parametre. Možete definisati anonimnu funkciju (bez imena) koja vraća cijeli broj plus jedan: -```tut +```scala mdoc (x: Int) => x + 1 ``` @@ -107,21 +107,21 @@ Na lijevoj strani `=>` je lista parametara. Na desnoj strani je izraz koji koris Funkcije možete i imenovati. -```tut +```scala mdoc val addOne = (x: Int) => x + 1 println(addOne(1)) // 2 ``` Funkcije mogu imati više parametara. -```tut +```scala mdoc val add = (x: Int, y: Int) => x + y println(add(1, 2)) // 3 ``` Ili bez parametara. -```tut +```scala mdoc val getTheAnswer = () => 42 println(getTheAnswer()) // 42 ``` @@ -132,7 +132,7 @@ Metode izgledaju i ponašaju se vrlo slično funkcijama, ali postoji nekoliko ra Metode se definišu ključnom riječju `def`. Nakon `def` slijedi naziv, lista parametara, povratni tip, i tijelo. -```tut +```scala mdoc:nest def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3 ``` @@ -141,14 +141,14 @@ Primijetite da je povratni tip deklarisan _nakon_ liste parametara i dvotačke ` Metode mogu imati više listi parametara. -```tut +```scala mdoc def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9 ``` Ili bez listi parametara ikako. -```tut +```scala mdoc def name: String = System.getProperty("name") println("Hello, " + name + "!") ``` @@ -158,7 +158,7 @@ Postoje i neke druge razlike, ali zasad, možete misliti o njima kao nečemu sli Metode mogu imati višelinijske izraze također. {% scalafiddle %} -```tut +```scala mdoc def getSquareString(input: Double): String = { val square = input * input square.toString @@ -173,7 +173,7 @@ Zadnjo izraz u tijelu metode je povratna vrijednost metode. (Scala ima ključnu Klasu možete definisati ključnom riječju `class` praćenom imenom i parametrima konstruktora. -```tut +```scala mdoc class Greeter(prefix: String, suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) @@ -186,7 +186,7 @@ Ne prenosi nikakvu korisnu informaciju.) Instancu klase možete kreirati pomoću ključne riječi `new`. -```tut +```scala mdoc val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` @@ -198,13 +198,13 @@ Detaljniji pregled klasa biće dat [kasnije](classes.html). Scala ima poseban tip klase koji se zove "case" klasa. Po defaultu, case klase su nepromjenjive i porede se po vrijednosti. Možete ih definisati s `case class` ključnim riječima. -```tut +```scala mdoc case class Point(x: Int, y: Int) ``` Instancu case klase možete kreirati i bez ključne riječi `new`. -```tut +```scala mdoc val point = Point(1, 2) val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2) @@ -212,7 +212,7 @@ val yetAnotherPoint = Point(2, 2) I porede se po vrijednosti. -```tut +```scala mdoc if (point == anotherPoint) { println(point + " and " + anotherPoint + " are the same.") } else { @@ -235,7 +235,7 @@ Objasnićemo ih u dubinu [kasnije](case-classes.html). Objekti su jedine instance svojih definicija. Možete misliti o njima kao singltonima svoje vlastite klase. Objekte možete definisati ključnom riječju `object`. -```tut +```scala mdoc object IdFactory { private var counter = 0 def create(): Int = { @@ -247,7 +247,7 @@ object IdFactory { Objektima možete pristupati referenciranjem njihovog imena. -```tut +```scala mdoc val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() @@ -262,7 +262,7 @@ Trejtovi su tipovi koji sadrže polja i metode. Više trejtova se može kombino Definišu se pomoću `trait` ključne riječi. -```tut +```scala mdoc:nest trait Greeter { def greet(name: String): Unit } @@ -270,7 +270,7 @@ trait Greeter { Metode trejtova mogu imati defaultnu implementaciju. -```tut +```scala mdoc:reset trait Greeter { def greet(name: String): Unit = println("Hello, " + name + "!") @@ -279,7 +279,7 @@ trait Greeter { Možete naslijediti trejtove s `extends` ključnom riječi i redefinisati (override) implementacije s `override` ključnom riječi. -```tut +```scala mdoc class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { @@ -306,7 +306,7 @@ Java Virtuelna Mašina traži da se glavna metoda zove `main` i da prima jedan a Koristeći objekt, možete definisati glavnu metodu ovako: -```tut +```scala mdoc object Main { def main(args: Array[String]): Unit = println("Hello, Scala developer!") diff --git a/_ba/tour/by-name-parameters.md b/_ba/tour/by-name-parameters.md index e166f5242f..5cfc42f8cb 100644 --- a/_ba/tour/by-name-parameters.md +++ b/_ba/tour/by-name-parameters.md @@ -13,7 +13,7 @@ previous-page: operators _By-name parametri_ (u slobodnom prevodu "po-imenu parametri") se izračunavaju samo kada se koriste. Oni su kontrastu sa _by-value parametrima_ ("po-vrijednosti parametri"). Da bi parametar bio pozivan by-name, dodajte `=>` prije njegovog tipa. -```tut +```scala mdoc def calculate(input: => Int) = input * 37 ``` By-name parametri imaju prednost da se ne izračunavaju ako se ne koriste u tijelu funkcije. @@ -21,7 +21,7 @@ U drugu ruku, by-value parametri imaju prednost da se izračunavaju samo jednom. Ovo je primjer kako bi mogli implementirati while petlju: -```tut +```scala mdoc def whileLoop(condition: => Boolean)(body: => Unit): Unit = if (condition) { body diff --git a/_ba/tour/case-classes.md b/_ba/tour/case-classes.md index a4cac6fad7..0c6de6d7b4 100644 --- a/_ba/tour/case-classes.md +++ b/_ba/tour/case-classes.md @@ -17,7 +17,7 @@ U sljedećem koraku turneje, vidjećemo kako su korisne u [podudaranju uzoraka ( ## Definisanje case klase Minimalna case klasa se sastoji iz ključnih riječi `case class`, identifikatora, i liste parametara (koja može biti prazna): -```tut +```scala mdoc case class Book(isbn: String) val frankenstein = Book("978-0486282114") diff --git a/_ba/tour/classes.md b/_ba/tour/classes.md index 534b1c6f27..29f170dca0 100644 --- a/_ba/tour/classes.md +++ b/_ba/tour/classes.md @@ -18,7 +18,7 @@ Tipovi, objekti i trejtovi biće pokriveni kasnije. ## Definisanje klase Minimalna definicija klase sastoji se od riječi `class` i identifikatora. Imena klasa bi trebala počinjati velikim slovom. -```tut +```scala mdoc class User val user1 = new User @@ -28,7 +28,7 @@ Ključna riječ `new` koristi se za kreiranje instance klase. Međutim, često ćete imati konstruktor i tijelo klase. Slijedi definicija klase `Point` (en. tačka): -```tut +```scala mdoc class Point(var x: Int, var y: Int) { def move(dx: Int, dy: Int): Unit = { @@ -56,7 +56,7 @@ Pošto `toString` prebrisava metodu `toString` iz [`AnyRef`](unified-types.html) Konstruktori mogu imati opcione parametre koristeći podrazumijevane vrijednosti: -```tut +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val origin = new Point // x and y are both set to 0 @@ -67,7 +67,7 @@ println(point1.x) // prints 1 U ovoj verziji klase `Point`, `x` i `y` imaju podrazumijevanu vrijednost `0` tako da ne morate proslijediti argumente. Međutim, pošto se argumenti konstruktora čitaju s lijeva na desno, ako želite proslijediti samo `y` vrijednost, morate imenovati parametar. -``` +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val point2 = new Point(y=2) println(point2.y) // prints 2 @@ -78,7 +78,7 @@ Ovo je također dobra praksa zbog poboljšanja čitljivosti. ## Privatni članovi i sintaksa getera/setera Članovi su javni (`public`) po defaultu. Koristite `private` modifikator pristupa da sakrijete članove klase. -```tut +```scala mdoc:nest class Point { private var _x = 0 private var _y = 0 @@ -108,14 +108,14 @@ Primijetite specijalnu sintaksu za setere: metoda ima `_=` nadodano na identifik Parametri primarnog konstruktora s `val` i `var` su javni. Međutim, pošto su `val` nepromjenjivi, ne možete napisati sljedeće. -``` +```scala mdoc:fail class Point(val x: Int, val y: Int) val point = new Point(1, 2) point.x = 3 // <-- does not compile ``` Parametri bez `val` ili `var` su privatne vrijednosti, vidljive samo unutar klase. -``` +```scala mdoc:fail class Point(x: Int, y: Int) val point = new Point(1, 2) point.x // <-- does not compile diff --git a/_ba/tour/compound-types.md b/_ba/tour/compound-types.md index 316d874c85..3781e866e3 100644 --- a/_ba/tour/compound-types.md +++ b/_ba/tour/compound-types.md @@ -15,7 +15,7 @@ U Scali ovo može biti izraženo pomoću *složenih tipova*, koji su presjeci ti Pretpostavimo da imamo dva trejta: `Cloneable` i `Resetable`: -```tut +```scala mdoc trait Cloneable extends java.lang.Cloneable { override def clone(): Cloneable = { super.clone().asInstanceOf[Cloneable] diff --git a/_ba/tour/default-parameter-values.md b/_ba/tour/default-parameter-values.md index 38be16bcc1..f4fc257900 100644 --- a/_ba/tour/default-parameter-values.md +++ b/_ba/tour/default-parameter-values.md @@ -13,7 +13,7 @@ prerequisite-knowledge: named-arguments, function syntax Scala omogućuje davanje podrazumijevanih vrijednosti parametrima koje dozvoljavaju korisniku metode da izostavi te parametre. -```tut +```scala mdoc def log(message: String, level: String = "INFO") = println(s"$level: $message") log("System starting") // prints INFO: System starting @@ -22,7 +22,7 @@ log("User not found", "WARNING") // prints WARNING: User not found Parametar `level` ima podrazumijevanu vrijednost tako da je opcioni. Na zadnjoj liniji, argument `"WARNING"` prebrisava podrazumijevani argument `"INFO"`. Gdje biste koristili overloadane metode u Javi, možete koristiti metode s opcionim parametrima da biste postigli isti efekat. Međutim, ako korisnik izostavi argument, bilo koji sljedeći argumenti moraju biti imenovani. -```tut +```scala mdoc class Point(val x: Double = 0, val y: Double = 0) val point1 = new Point(y = 1) @@ -31,7 +31,7 @@ Ovdje moramo reći `y = 1`. Podrazumijevani parametri u Scali nisu opcioni kada se koriste iz Java koda: -```tut +```scala mdoc:reset // Point.scala class Point(val x: Double = 0, val y: Double = 0) ``` diff --git a/_ba/tour/extractor-objects.md b/_ba/tour/extractor-objects.md index 979f2d4250..ac948e255d 100644 --- a/_ba/tour/extractor-objects.md +++ b/_ba/tour/extractor-objects.md @@ -14,7 +14,7 @@ Ekstraktor objekat je objekat koji ima `unapply` metodu. Dok je `apply` metoda kao konstruktor koji uzima argumente i kreira objekat, `unapply` metoda prima objekat i pokušava vratiti argumente. Ovo se najčešće koristi u podudaranju uzoraka i parcijalnim funkcijama. -```tut +```scala mdoc import scala.util.Random object CustomerID { @@ -41,7 +41,7 @@ Kada pozovemo `case CustomerID(name) => customer1ID`, ustvari pozivamo `unapply` Metoda `unapply` se može koristiti i za dodjelu vrijednosti. -```tut +```scala mdoc val customer2ID = CustomerID("Nico") val CustomerID(name) = customer2ID println(name) // prints Nico @@ -49,7 +49,7 @@ println(name) // prints Nico Ovo je ekvivalentno `val name = CustomerID.unapply(customer2ID).get`. Ako se uzorak ne podudari, baciće se `scala.MatchError` izuzetak: -```tut:fail +```scala mdoc:crash val CustomerID(name2) = "--asdfasdfasdf" ``` diff --git a/_ba/tour/for-comprehensions.md b/_ba/tour/for-comprehensions.md index efdeb57dc8..7064a95894 100644 --- a/_ba/tour/for-comprehensions.md +++ b/_ba/tour/for-comprehensions.md @@ -21,7 +21,7 @@ Komprehensija evaluira tijelo `e` za svako vezivanje varijable generisano od str Slijedi primjer: -```tut +```scala mdoc case class User(name: String, age: Int) val userBase = List(User("Travis", 28), @@ -38,7 +38,7 @@ twentySomethings.foreach(name => println(name)) // prints Travis Dennis Slijedi malo komplikovaniji primjer koji s dva generatora. Izračunava sve parove brojeva između `0` i `n-1` čija je suma jednaka vrijednosti `v`: -```tut +```scala mdoc def foo(n: Int, v: Int) = for (i <- 0 until n; j <- i until n if i + j == v) diff --git a/_ba/tour/generic-classes.md b/_ba/tour/generic-classes.md index c86d8f3f8f..63ce385f2c 100644 --- a/_ba/tour/generic-classes.md +++ b/_ba/tour/generic-classes.md @@ -19,7 +19,7 @@ Vrlo su korisne za implementiranje kolekcija. Generičke klase primaju tip kao parametar u uglastim zagradama `[]`. Konvencija je da se koristi slovo `A` kao identifikator tipa, mada se može koristiti bilo koje ime. -```tut +```scala mdoc class Stack[A] { private var elements: List[A] = Nil def push(x: A) { elements = x :: elements } diff --git a/_ba/tour/higher-order-functions.md b/_ba/tour/higher-order-functions.md index e7ac3103aa..8ddead84a5 100644 --- a/_ba/tour/higher-order-functions.md +++ b/_ba/tour/higher-order-functions.md @@ -14,7 +14,7 @@ Scala dozvoljava definisanje funkcija višeg reda. To su funkcije koje _primaju druge funkcije kao parametre_, ili čiji je _rezultat funkcija_. Ovo je funkcija `apply` koja uzima drugu funkciju `f` i vrijednost `v` i primjenjuje funkciju `f` na `v`: -```tut +```scala mdoc def apply(f: Int => String, v: Int) = f(v) ``` @@ -22,13 +22,13 @@ _Napomena: metode se automatski pretvaraju u funkcije ako to kontekst zahtijeva. Ovo je još jedan primjer: -```tut +```scala mdoc class Decorator(left: String, right: String) { def layout[A](x: A) = left + x.toString() + right } object FunTest extends App { - def apply(f: Int => String, v: Int) = f(v) + override def apply(f: Int => String, v: Int) = f(v) val decorator = new Decorator("[", "]") println(apply(decorator.layout, 7)) } diff --git a/_ba/tour/implicit-conversions.md b/_ba/tour/implicit-conversions.md index 090dc03323..d794590c45 100644 --- a/_ba/tour/implicit-conversions.md +++ b/_ba/tour/implicit-conversions.md @@ -43,7 +43,7 @@ Implicitno importovani objekt `scala.Predef` deklariše nekoliko predefinisanih Naprimjer, kada se pozivaju Javine metode koje očekuju `java.lang.Integer`, možete proslijediti `scala.Int`. Možete, zato što `Predef` uključuje slj. implicitnu konverziju: -```tut +```scala mdoc import scala.language.implicitConversions implicit def int2Integer(x: Int) = diff --git a/_ba/tour/implicit-parameters.md b/_ba/tour/implicit-parameters.md index 5b50d8f5e9..c39d87d626 100644 --- a/_ba/tour/implicit-parameters.md +++ b/_ba/tour/implicit-parameters.md @@ -22,7 +22,7 @@ Argumenti koji se mogu proslijediti kao implicitni parametri spadaju u dvije kat U sljedećem primjeru definisaćemo metodu `sum` koja izračunava sumu liste elemenata koristeći `add` i `unit` operacije monoida. Molimo primijetite da implicitne vrijednosti ne mogu biti top-level, već moraju biti članovi templejta. -```tut +```scala mdoc abstract class SemiGroup[A] { def add(x: A, y: A): A } diff --git a/_ba/tour/inner-classes.md b/_ba/tour/inner-classes.md index 41dd73ed91..10eac53bfb 100644 --- a/_ba/tour/inner-classes.md +++ b/_ba/tour/inner-classes.md @@ -17,7 +17,7 @@ Pretpostavimo da želimo da nas kompejler spriječi da pomiješamo koji čvorovi Radi ilustracije razlike, prikazaćemo implementaciju klase grafa: -```tut +```scala mdoc class Graph { class Node { var connectedNodes: List[Node] = Nil @@ -39,7 +39,7 @@ class Graph { U našem programu, grafovi su predstavljeni listom čvorova (`List[Node]`). Svaki čvor ima listu drugih čvorova s kojima je povezan (`connectedNodes`). Klasa `Node` je _path-dependent tip_ jer je ugniježdena u klasi `Graph`. Stoga, svi čvorovi u `connectedNodes` moraju biti kreirani koristeći `newNode` iz iste instance klase `Graph`. -```tut +```scala mdoc val graph1: Graph = new Graph val node1: graph1.Node = graph1.newNode val node2: graph1.Node = graph1.newNode @@ -54,7 +54,7 @@ Da imamo dva grafa, sistem tipova Scale ne dozvoljava miješanje čvorova defin jer čvorovi različitih grafova imaju različit tip. Ovo je primjer netačnog programa: -``` +```scala mdoc:fail val graph1: Graph = new Graph val node1: graph1.Node = graph1.newNode val node2: graph1.Node = graph1.newNode @@ -70,7 +70,7 @@ Za čvorove oba grafa, Java bi dodijelila isti tip `Graph.Node`; npr. `Node` bi U Scali takav tip je također moguće izraziti, piše se kao `Graph#Node`. Ako želimo povezati čvorove različitih grafova, moramo promijeniti definiciju naše inicijalne implementacije grafa: -```tut +```scala mdoc:nest class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil diff --git a/_ba/tour/lower-type-bounds.md b/_ba/tour/lower-type-bounds.md index 8261a2e77c..85dd54a401 100644 --- a/_ba/tour/lower-type-bounds.md +++ b/_ba/tour/lower-type-bounds.md @@ -17,7 +17,7 @@ Izraz `B >: A` izražava tipski parametar `B` ili apstraktni tip `B` koji je nad Kroz sljedeći primjer vidjećemo zašto je ovo korisno: -```tut:fail +```scala mdoc:fail trait Node[+B] { def prepend(elem: B): Node[B] } @@ -43,7 +43,7 @@ Ovo ne radi jer su funkcije *kontra*varijantne u svojim tipovima parametara i *k Da bismo popravili ovo, moramo zamijeniti varijansu tipskog parametra `elem` u `prepend`. Ovo radimo uvođenjem novog tipskog parametra `U` koji ima `B` kao svoju donju granicu tipa. -```tut +```scala mdoc trait Node[+B] { def prepend[U >: B](elem: U): Node[U] } @@ -60,7 +60,7 @@ case class Nil[+B]() extends Node[B] { ``` Sada možemo uraditi sljedeće: -```tut +```scala mdoc trait Bird case class AfricanSwallow() extends Bird case class EuropeanSwallow() extends Bird diff --git a/_ba/tour/mixin-class-composition.md b/_ba/tour/mixin-class-composition.md index 66ad5f623e..a38c2ba2e1 100644 --- a/_ba/tour/mixin-class-composition.md +++ b/_ba/tour/mixin-class-composition.md @@ -13,7 +13,7 @@ prerequisite-knowledge: inheritance, traits, abstract-classes, unified-types Mixini su trejtovi koji se koriste za kompoziciju klase. -```tut +```scala mdoc abstract class A { val message: String } @@ -34,7 +34,7 @@ Klase mogu imati samo jednu nadklasu alid mogu imati više mixina (koristeći kl Pogledajmo sada zanimljiviji primjer počevši od apstraktne klase: -```tut +```scala mdoc abstract class AbsIterator { type T def hasNext: Boolean @@ -45,7 +45,7 @@ abstract class AbsIterator { Klasa ima apstraktni tip `T` i standardne metode iteratora. Dalje, implementiraćemo konkretnu klasu (svi apstraktni članovi `T`, `hasNext`, i `next` imaju implementacije): -```tut +```scala mdoc class StringIterator(s: String) extends AbsIterator { type T = Char private var i = 0 @@ -66,7 +66,7 @@ class StringIterator(s: String) extends AbsIterator { Kreirajmo sada trejt koji također nasljeđuje `AbsIterator`. -```tut +```scala mdoc trait RichIterator extends AbsIterator { def foreach(f: T => Unit): Unit = while (hasNext) f(next()) } @@ -76,7 +76,7 @@ Pošto je `RichIterator` trejt, on ne mora implementirati apstraktne članove `A Željeli bismo iskombinirati funkcionalnosti `StringIterator`a i `RichIterator`a u jednoj klasi. -```tut +```scala mdoc object StringIteratorTest extends App { class Iter extends StringIterator("Scala") with RichIterator val iter = new Iter diff --git a/_ba/tour/multiple-parameter-lists.md b/_ba/tour/multiple-parameter-lists.md index ed9f22c1b1..68230aa12b 100644 --- a/_ba/tour/multiple-parameter-lists.md +++ b/_ba/tour/multiple-parameter-lists.md @@ -16,7 +16,7 @@ onda će to vratiti funkciju koja prima preostale liste parametara kao argumente Primjer: -```tut +```scala mdoc object CurryTest extends App { def filter(xs: List[Int], p: Int => Boolean): List[Int] = diff --git a/_ba/tour/named-arguments.md b/_ba/tour/named-arguments.md index abe434c3b4..6656b02da2 100644 --- a/_ba/tour/named-arguments.md +++ b/_ba/tour/named-arguments.md @@ -12,7 +12,7 @@ prerequisite-knowledge: function-syntax Kada se pozivaju metode, možete koristiti imena varijabli eksplicitno pri pozivu: -```tut +```scala mdoc def printName(first: String, last: String): Unit = { println(first + " " + last) } diff --git a/_ba/tour/nested-functions.md b/_ba/tour/nested-functions.md index 7c4adc75b2..1a00eaba59 100644 --- a/_ba/tour/nested-functions.md +++ b/_ba/tour/nested-functions.md @@ -13,7 +13,7 @@ previous-page: higher-order-functions U Scali je moguće ugnježdavati definicije metode. Sljedeći objekt sadrži metodu `factorial` za računanje faktorijela datog broja: -```tut +```scala mdoc def factorial(x: Int): Int = { def fact(x: Int, accumulator: Int): Int = { if (x <= 1) accumulator diff --git a/_ba/tour/operators.md b/_ba/tour/operators.md index 259fdca8fe..e16e338132 100644 --- a/_ba/tour/operators.md +++ b/_ba/tour/operators.md @@ -25,7 +25,7 @@ Međutim, lakše je čitati kada se napiše kao infiksni operator: ## Definisanje i korištenje operatora Možete koristiti bilo koji legalni identifikator kao operator. To uključuje i imena kao `add` ili simbole kao `+`. -```tut +```scala mdoc case class Vec(x: Double, y: Double) { def +(that: Vec) = Vec(this.x + that.x, this.y + that.y) } @@ -42,7 +42,7 @@ Koristeći zagrade, možete pisati kompleksne izraze s čitljivom sintaksom. Slijedi definicija klase `MyBool` koja definiše tri metode `and`, `or`, i `negate`. -```tut +```scala mdoc case class MyBool(x: Boolean) { def and(that: MyBool): MyBool = if (x) that else this def or(that: MyBool): MyBool = if (x) this else that @@ -52,7 +52,7 @@ case class MyBool(x: Boolean) { Sada je moguće koristiti `and` i `or` kao infiksne operatore: -```tut +```scala mdoc def not(x: MyBool) = x.negate def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y) ``` diff --git a/_ba/tour/pattern-matching.md b/_ba/tour/pattern-matching.md index 6c902033a2..e303e05d63 100644 --- a/_ba/tour/pattern-matching.md +++ b/_ba/tour/pattern-matching.md @@ -16,7 +16,7 @@ Podudaranje uzoraka je mehanizam za provjeranje da li vrijednost odgovara uzroku ## Sintaksa Izraz za podudaranje ima vrijednost, `match` ključnu riječ, i bar jednu `case` klauzu. -```tut +```scala mdoc import scala.util.Random val x: Int = Random.nextInt(10) @@ -34,7 +34,7 @@ Zadnji slučaj, `_`, je "uhvati sve" slučaj za brojeve veće od 2. Slučajevi se još zovu i _alternative_. Izrazi za podudaranje imaju vrijednost. -```tut +```scala mdoc def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" @@ -50,7 +50,7 @@ Stoga, metoda `matchTest` vraća `String`. Case klase su posebno korisne za podudaranje uzoraka. -```tut +```scala mdoc abstract class Notification case class Email(sender: String, title: String, body: String) extends Notification @@ -118,7 +118,7 @@ U `case Email(email, _, _) if importantPeopleInfo.contains(email)`, uzorak se po ## Podudaranje samo tipa Možete podudarati samo tip ovako: -```tut +```scala mdoc abstract class Device case class Phone(model: String) extends Device { def screenOff = "Turning screen off" @@ -140,7 +140,7 @@ Konvencija je da se koristi prvo slovo tipa kao identifikator (`p` i `c` ovdje). Trejtovi i klase mogu biti `sealed` što znači da svi podtipovi moraju biti reklarisani u istom fajlu. Ovo osigurava da su svi podtipovi poznati. -```tut +```scala mdoc sealed abstract class Furniture case class Couch() extends Furniture case class Chair() extends Furniture diff --git a/_ba/tour/polymorphic-methods.md b/_ba/tour/polymorphic-methods.md index 2fcb672428..a5ad6e27f4 100644 --- a/_ba/tour/polymorphic-methods.md +++ b/_ba/tour/polymorphic-methods.md @@ -18,7 +18,7 @@ Vrijednosni parameteri ("obični") su ograđeni parom zagrada, dok su tipski par Slijedi primjer: -```tut +```scala mdoc def listOfDuplicates[A](x: A, length: Int): List[A] = { if (length < 1) Nil diff --git a/_ba/tour/regular-expression-patterns.md b/_ba/tour/regular-expression-patterns.md index 6936f74013..558b039a24 100644 --- a/_ba/tour/regular-expression-patterns.md +++ b/_ba/tour/regular-expression-patterns.md @@ -14,7 +14,7 @@ previous-page: singleton-objects Regularni izrazi su stringovi koji se mogu koristiti za traženje uzoraka u podacima. Bilo koji string se može pretvoriti u regularni izraz pozivom `.r` metode. -```tut +```scala mdoc import scala.util.matching.Regex val numberPattern: Regex = "[0-9]".r @@ -30,7 +30,7 @@ U gornjem primjeru, `numberPattern` je `Regex` Također, možete tražiti grupe regularnih izraza koristeći zagrade. -```tut +```scala mdoc import scala.util.matching.Regex val keyValPattern: Regex = "([0-9a-zA-Z-#() ]+): ([0-9a-zA-Z-#() ]+)".r diff --git a/_ba/tour/self-types.md b/_ba/tour/self-types.md index da47a626bc..9b0ccd95a2 100644 --- a/_ba/tour/self-types.md +++ b/_ba/tour/self-types.md @@ -17,7 +17,7 @@ Self-tip je način da se suzi tip `this` ili drugi identifikator koji je alijas Sintaksa izgleda kao obična funkcija ali znači nešto sasvim drugačije. Da bi koristili self-tip u trejtu, napišite identifikator, tip drugog trejta za umiksavanje, i `=>` (tj. `someIdentifier: SomeOtherTrait =>`). -```tut +```scala mdoc trait User { def username: String } diff --git a/_ba/tour/singleton-objects.md b/_ba/tour/singleton-objects.md index 7c74f5318e..7f8ac84ba4 100644 --- a/_ba/tour/singleton-objects.md +++ b/_ba/tour/singleton-objects.md @@ -44,7 +44,7 @@ ako krug s velikim “C” ili “O” ima savijenu ivicu (kao papir), možete k Klasa i njen kompanjon objekt, ako ga ima, moraju biti definisani u istom izvornom fajlu: -```tut +```scala mdoc class IntPair(val x: Int, val y: Int) object IntPair { diff --git a/_ba/tour/traits.md b/_ba/tour/traits.md index 6d0356cda0..8f7a82cc9e 100644 --- a/_ba/tour/traits.md +++ b/_ba/tour/traits.md @@ -18,12 +18,12 @@ Klase i objekti mogu naslijediti trejtove ali trejtovi ne mogu biti instancirani ## Definisanje trejta Minimalni trejt je samo ključna riječ `trait` i identifikator: -```tut +```scala mdoc trait HairColor ``` Trejtovi su vrlo korisni s generičkim tipovima i apstraktnim metodama. -```tut +```scala mdoc trait Iterator[A] { def hasNext: Boolean def next(): A @@ -34,7 +34,7 @@ Nasljeđivanje `trait Iterator[A]` traži tip `A` i implementacije metoda `hasNe ## Korištenje trejtova Koristite `extends` za nasljeđivanje trejta. Zatim implementirajte njegove apstraktne članove koristeći `override` ključnu riječ: -```tut +```scala mdoc:nest trait Iterator[A] { def hasNext: Boolean def next(): A @@ -62,7 +62,7 @@ Ona nasljeđuje `Iterator[Int]` što znači da `next` mora vraćati `Int`. ## Podtipovi Podtipovi trejtova mogu se koristiti gdje se trejt traži. -```tut +```scala mdoc import scala.collection.mutable.ArrayBuffer trait Pet { diff --git a/_ba/tour/tuples.md b/_ba/tour/tuples.md index 34bceaa3d1..99f49e7247 100644 --- a/_ba/tour/tuples.md +++ b/_ba/tour/tuples.md @@ -10,4 +10,4 @@ previous-page: traits --- (this section of the tour has not been translated yet. pull request -with translation welcome!) \ No newline at end of file +with translation welcome!) diff --git a/_ba/tour/type-inference.md b/_ba/tour/type-inference.md index 3ff6ab6ce6..d3b7eb1867 100644 --- a/_ba/tour/type-inference.md +++ b/_ba/tour/type-inference.md @@ -16,7 +16,7 @@ Povratni tipovi metoda također mogu biti izostavljeni jer oni odgovaraju tipu t Slijedi jedan primjer: -```tut +```scala mdoc object InferenceTest1 extends App { val x = 1 + 2 * 3 // the type of x is Int val y = x.toString() // the type of y is String @@ -27,7 +27,7 @@ object InferenceTest1 extends App { Za rekurzivne metode, kompajler nije u mogućnosti da zaključi tip rezultata. Ovo je program koji se ne može kompajlirati iz ovog razloga: -```tut:fail +```scala mdoc:fail object InferenceTest2 { def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) } @@ -58,7 +58,7 @@ val y: Int = id[Int](1) U nekim situacijama može biti vrlo opasno osloniti se na Scalin mehanizam zaključivanja tipova: -```tut:fail +```scala mdoc:fail object InferenceTest4 { var obj = null obj = new Object() diff --git a/_ba/tour/unified-types.md b/_ba/tour/unified-types.md index 7f9787e5b9..c03e54ab0b 100644 --- a/_ba/tour/unified-types.md +++ b/_ba/tour/unified-types.md @@ -34,7 +34,7 @@ Ako se Scala koristi u kontekstu JRE, onda `AnyRef` odgovara klasi `java.lang.Ob Slijedi primjer koji demonstrira da su stringovi, integeri, karakteri, booleani i funkcije svi objekti kao bilo koji drugi: -```tut +```scala mdoc val list: List[Any] = List( "a string", 732, // an integer @@ -64,7 +64,7 @@ Vrijednosni tipovi mogu biti kastovani na sljedeći način: Npr: -```tut +```scala mdoc val x: Long = 987654321 val y: Float = x // 9.8765434E8 (određena doza preciznosti se gubi ovdje) diff --git a/_ba/tour/upper-type-bounds.md b/_ba/tour/upper-type-bounds.md index ce4f4e198e..e91d904d5d 100644 --- a/_ba/tour/upper-type-bounds.md +++ b/_ba/tour/upper-type-bounds.md @@ -15,7 +15,7 @@ Takve granice tipa ograničavaju konkretne vrijednosti tipskih varijabli i ponek _Gornja granica tipa_ `T <: A` kaže da se tipska varijabla `T` odnosi na podtip tipa `A`. Slijedi primjer koji demonstrira gornju granicu tipa za tipski parametar klase `PetContainer`: -```tut +```scala mdoc abstract class Animal { def name: String } @@ -42,7 +42,7 @@ val dogContainer = new PetContainer[Dog](new Dog) val catContainer = new PetContainer[Cat](new Cat) ``` -```tut:fail +```scala mdoc:fail val lionContainer = new PetContainer[Lion](new Lion) // this would not compile ``` Klasa `PetContainer` prima tipski parametar `P` koji mora biti podtip od `Pet`. diff --git a/_ba/tour/variances.md b/_ba/tour/variances.md index 0540982844..2920e00dac 100644 --- a/_ba/tour/variances.md +++ b/_ba/tour/variances.md @@ -14,7 +14,7 @@ Varijansa je korelacija podtipskih veza kompleksnih tipova i podtipskih veza nji Scala podržava anotacije varijanse tipskih parametara [generičkih klasa](generic-classes.html), dozvoljavajući im da budu kovarijantni, kontravarijantni, ili invarijantni ako se anotacije ne koriste. Korištenje varijanse u sistemu tipova dozvoljava pravljenje intuitivnijih veza među kompleksnim tipovima, a nedostatak varijanse može ograničiti ponovno iskorištenje klasne apstrakcije. -```tut +```scala mdoc class Foo[+A] // kovarijantna klasa class Bar[-A] // kontravarijantna klasa class Baz[A] // invarijantna klasa @@ -28,7 +28,7 @@ Ovo dozvoljava pravljenje vrlo intuitivnih podtipskih veza koristeći generiku. Razmotrite sljedeću strukturu klasa: -```tut +```scala mdoc abstract class Animal { def name: String } @@ -44,7 +44,7 @@ Intuitivno, ima smisla da su lista mačaka i lista pasa također liste životinj U sljedećem primjeru, metoda `printAnimalNames` prima listu životinja kao argument i ispisuje njihova imena, svako na idućoj liniji. Da `List[A]` nije kovarijantna, zadnja dva poziva metode se ne bi kompajlirali, što bi značajno ograničilo korisnost `printAnimalNames` metode. -```tut +```scala mdoc object CovarianceTest extends App { def printAnimalNames(animals: List[Animal]): Unit = { animals.foreach { animal => @@ -73,7 +73,7 @@ To jest, za neku `class Writer[-A]`, kontravarijantno `A` znači da za dva tipa Razmotrimo `Cat`, `Dog`, i `Animal` klase u sljedećem primjeru: -```tut +```scala mdoc abstract class Printer[-A] { def print(value: A): Unit } @@ -81,7 +81,7 @@ abstract class Printer[-A] { `Printer[A]` je jednostavna klasa koja zna ispisati neki tip `A`. Definišimo neke podklase za specifične tipove: -```tut +```scala mdoc class AnimalPrinter extends Printer[Animal] { def print(animal: Animal): Unit = println("The animal's name is: " + animal.name) @@ -99,7 +99,7 @@ Inverzna veza ne vrijedi, jer `Printer[Cat]` ne zna kako da ispiše bilo koju `A Stoga, terbali bismo moći zamijeniti `Printer[Animal]` za `Printer[Cat]`, ako želimo, i praveći `Printer[A]` kontravarijantnim nam to dozvoljava. -```tut +```scala mdoc object ContravarianceTest extends App { val myCat: Cat = Cat("Boots") @@ -129,7 +129,7 @@ Ovo znač da nisu ni kovarijantne ni kontravarijantne. U kontekstu sljedećeg primjera, `Container` klasa je invarijantna. `Container[Cat]` _nije_ `Container[Animal]`, niti obrnuto. -```tut +```scala mdoc class Container[A](value: A) { private var _value: A = value def getValue: A = _value @@ -162,7 +162,7 @@ Za ovaj primjer koristićemo literal notaciju `A => B` za predstavljanje `Functi Pretpostavimo da imamo sličnu hijerarhiju klasa `Cat`, `Dog`, `Animal` otprije, plus sljedeće: -```tut +```scala mdoc class SmallAnimal class Mouse extends SmallAnimal ``` diff --git a/_books/5-functional-programming-in-scala.md b/_books/5-functional-programming-in-scala.md index e90d36e92d..97a64d3a15 100644 --- a/_books/5-functional-programming-in-scala.md +++ b/_books/5-functional-programming-in-scala.md @@ -8,4 +8,4 @@ publisher: Manning publisherLink: https://www.manning.com/ --- -"Functional programming (FP) is a style of software development emphasizing functions that don't depend on program state... Functional Programming in Scala is a serious tutorial for programmers looking to learn FP and apply it to the everyday business of coding. The book guides readers from basic techniques to advanced topics in a logical, concise, and clear progression. In it, you'll find concrete examples and exercises that open up the world of functional programming." \ No newline at end of file +"Functional programming (FP) is a style of software development emphasizing functions that don't depend on program state... Functional Programming in Scala is a serious tutorial for programmers looking to learn FP and apply it to the everyday business of coding. The book guides readers from basic techniques to advanced topics in a logical, concise, and clear progression. In it, you'll find concrete examples and exercises that open up the world of functional programming." diff --git a/_es/tour/abstract-type-members.md b/_es/tour/abstract-type-members.md index ffcf7fd482..841fa8778e 100644 --- a/_es/tour/abstract-type-members.md +++ b/_es/tour/abstract-type-members.md @@ -14,56 +14,62 @@ previous-page: tour-of-scala En Scala, las cases son parametrizadas con valores (los parámetros de construcción) y con tipos (si las clases son [genéricas](generic-classes.html)). Por razones de consistencia, no es posible tener solo valores como miembros de objetos; tanto los tipos como los valores son miembros de objetos. Además, ambos tipos de miembros pueden ser concretos y abstractos. A continuación un ejemplo el cual define de forma conjunta una asignación de valor tardía y un tipo abstracto como miembros del [trait](traits.html) `Buffer`. - trait Buffer { - type T - val element: T - } +```scala mdoc +trait Buffer { + type T + val element: T +} +``` Los *tipos abstractos* son tipos los cuales su identidad no es precisamente conocida. En el ejemplo anterior, lo único que sabemos es que cada objeto de la clase `Buffer` tiene un miembro de tipo `T`, pero la definición de la clase `Buffer` no revela qué tipo concreto se corresponde con el tipo `T`. Tal como las definiciones de valores, es posible sobrescribir las definiciones de tipos en subclases. Esto permite revelar más información acerca de un tipo abstracto al acotar el tipo ligado (el cual describe las posibles instancias concretas del tipo abstracto). En el siguiente programa derivamos la clase `SeqBuffer` la cual nos permite almacenar solamente sequencias en el buffer al estipular que el tipo `T` tiene que ser un subtipo de `Seq[U]` para un nuevo tipo abstracto `U`: - abstract class SeqBuffer extends Buffer { - type U - type T <: Seq[U] - def length = element.length - } +```scala mdoc +abstract class SeqBuffer extends Buffer { + type U + type T <: Seq[U] + def length = element.length +} +``` Traits o [clases](classes.html) con miembros de tipos abstractos son generalmente usados en combinación con instancias de clases anónimas. Para ilustrar este concepto veremos un programa el cual trata con un buffer de sequencia que se remite a una lista de enteros. - abstract class IntSeqBuffer extends SeqBuffer { - type U = Int - } +```scala mdoc +abstract class IntSeqBuffer extends SeqBuffer { + type U = Int +} - object AbstractTypeTest1 extends App { - def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer = - new IntSeqBuffer { - type T = List[U] - val element = List(elem1, elem2) - } - val buf = newIntSeqBuf(7, 8) - println("length = " + buf.length) - println("content = " + buf.element) - } +object AbstractTypeTest1 extends App { + def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer = + new IntSeqBuffer { + type T = List[U] + val element = List(elem1, elem2) + } + val buf = newIntSeqBuf(7, 8) + println("length = " + buf.length) + println("content = " + buf.element) +} +``` El tipo retornado por el método `newIntSeqBuf` está ligado a la especialización del trait `Buffer` en el cual el tipo `U` es ahora equivalente a `Int`. Existe un tipo alias similar en la instancia de la clase anónima dentro del cuerpo del método `newIntSeqBuf`. En ese lugar se crea una nueva instancia de `IntSeqBuffer` en la cual el tipo `T` está ligado a `List[Int]`. Es necesario notar que generalmente es posible transformar un tipo abstracto en un tipo paramétrico de una clase y viceversa. A continuación se muestra una versión del código anterior el cual solo usa tipos paramétricos. - abstract class Buffer[+T] { - val element: T - } - abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] { - def length = element.length - } - object AbstractTypeTest2 extends App { - def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] = - new SeqBuffer[Int, List[Int]] { - val element = List(e1, e2) - } - val buf = newIntSeqBuf(7, 8) - println("length = " + buf.length) - println("content = " + buf.element) - } +```scala mdoc:reset +abstract class Buffer[+T] { + val element: T +} +abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] { + def length = element.length +} +def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] = + new SeqBuffer[Int, List[Int]] { + val element = List(e1, e2) + } +val buf = newIntSeqBuf(7, 8) +println("length = " + buf.length) +println("content = " + buf.element) +``` Nótese que es necesario usar [variance annotations](variances.html) aquí; de otra manera no sería posible ocultar el tipo implementado por la secuencia concreta del objeto retornado por `newIntSeqBuf`. Además, existen casos en los cuales no es posible remplazar tipos abstractos con tipos parametrizados. diff --git a/_es/tour/basics.md b/_es/tour/basics.md index 998ddbe544..ba3519ef02 100644 --- a/_es/tour/basics.md +++ b/_es/tour/basics.md @@ -27,14 +27,14 @@ Muchos ejemplos de código en esta documentación están integrados con ScalaFid Las expresiones son sentencias computables. -```tut +```scala mdoc 1 + 1 ``` Se puede ver el resultado de evaluar expresiones usando `println`. {% scalafiddle %} -```tut +```scala mdoc println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! @@ -46,7 +46,7 @@ println("Hello," + " world!") // Hello, world! Se puede dar un nombre al resultado de una expresión usando la palabra reservada `val`. -```tut +```scala mdoc val x = 1 + 1 println(x) // 2 ``` @@ -55,13 +55,13 @@ Los resultados con nombre, como `x` en el ejemplo, son llamados valores. Referen Los valores no pueden ser reasignados. -```tut:fail +```scala mdoc:fail x = 3 // This does not compile. ``` Scala es capaz de inferir el tipo de un valor. Aun así, también se puede indicar el tipo usando una anotación: -```tut +```scala mdoc:nest val x: Int = 1 + 1 ``` @@ -71,7 +71,7 @@ Nótese que la anotación del tipo `Int` sigue al identificador `x` de la variab Una variable es como un valor, excepto que a una variable se le puede re-asignar un valor después de declararla. Una variable se declara con la palabra reservada `var`. -```tut +```scala mdoc:nest var x = 1 + 1 x = 3 // This compiles because "x" is declared with the "var" keyword. println(x * x) // 9 @@ -79,7 +79,7 @@ println(x * x) // 9 Como con los valores, si se quiere se puede especificar el tipo de una variable mutable: -```tut +```scala mdoc:nest var x: Int = 1 + 1 ``` @@ -89,7 +89,7 @@ Se pueden combinar expresiones rodeándolas con `{}` . A esto le llamamos un blo El resultado de la última expresión del bloque es también el resultado total del bloque. -```tut +```scala mdoc println({ val x = 1 + 1 x + 1 @@ -102,7 +102,7 @@ Una función es una expresión que acepta parámetros. Una función se puede declarar anónima, sin nombre. Por ejemplo, ésta es una función que acepta un número entero `x`, y devuelve el resultado de incrementarlo: -```tut +```scala mdoc (x: Int) => x + 1 ``` @@ -111,7 +111,7 @@ La lista de parámetros de la función está a la izquierda de la flecha `=>`, y También podemos asignarle un nombre a la función. {% scalafiddle %} -```tut +```scala mdoc val addOne = (x: Int) => x + 1 println(addOne(1)) // 2 ``` @@ -120,7 +120,7 @@ println(addOne(1)) // 2 Las funciones pueden tomar varios parámetros. {% scalafiddle %} -```tut +```scala mdoc val add = (x: Int, y: Int) => x + y println(add(1, 2)) // 3 ``` @@ -128,7 +128,7 @@ println(add(1, 2)) // 3 O ninguno. -```tut +```scala mdoc val getTheAnswer = () => 42 println(getTheAnswer()) // 42 ``` @@ -140,7 +140,7 @@ Los métodos se parecen y comportan casi como a las funciones, pero se diferenci Un método se define con la palabra reservada `def`, seguida por el nombre del método, la lista de parámetros, el tipo de valores que el método devuelve, y el cuerpo del método. {% scalafiddle %} -```tut +```scala mdoc:nest def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3 ``` @@ -151,7 +151,7 @@ Observe que el tipo de retorno se declara _después_ de la lista de parámetros, Un método puede tener varias listas de parámetros. {% scalafiddle %} -```tut +```scala mdoc def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9 ``` @@ -159,7 +159,7 @@ println(addThenMultiply(1, 2)(3)) // 9 O ninguna lista de parámetros. -```tut +```scala mdoc def name: String = System.getProperty("user.name") println("Hello, " + name + "!") ``` @@ -169,7 +169,7 @@ Hay otras diferencias, pero para simplificar, podemos pensar que son similares a Los métodos también pueden tener expresiones de varias lineas. {% scalafiddle %} -```tut +```scala mdoc def getSquareString(input: Double): String = { val square = input * input square.toString @@ -185,7 +185,7 @@ La ultima expresión en el cuerpo del método es el valor de retorno del mismo. Una clase se define con la palabra reservada `class`, seguida del nombre, y la lista de parámetros del constructor. -```tut +```scala mdoc class Greeter(prefix: String, suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) @@ -196,7 +196,7 @@ El método `greet` tiene un tipo de retorno `Unit`, que indica que el método no Se puede crear una instancia de una clase con la palabra reservada *new*. -```tut +```scala mdoc val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` @@ -208,13 +208,13 @@ Las clases se tratan en profundidad [más adelante](classes.html). Hay un tipo especial de clases en Scala, las llamadas "case" classes. Por defecto, las instancias de una case class son inmutables, y se comparan con otras solo por los valores que contienen en cada campo. Una case class se define con las palabras reservadas `case class`: -```tut +```scala mdoc case class Point(x: Int, y: Int) ``` Se puede crear una instancia de una `case class`, sin usar la palabra reservada `new`. -```tut +```scala mdoc val point = Point(1, 2) val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2) @@ -222,7 +222,7 @@ val yetAnotherPoint = Point(2, 2) Y son comparadas por valor. -```tut +```scala mdoc if (point == anotherPoint) { println(point + " and " + anotherPoint + " are the same.") } else { @@ -244,7 +244,7 @@ Los objetos son instancias de una sola clase de su propia definición. Puedes pe Un objeto se define usando la palabra reservada `object`. -```tut +```scala mdoc object IdFactory { private var counter = 0 def create(): Int = { @@ -256,7 +256,7 @@ object IdFactory { Para acceder al objeto, lo referencias por su nombre. -```tut +```scala mdoc val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() @@ -271,7 +271,7 @@ Los traits son tipos que contienen campos y métodos. Se pueden combinar múltip Un trait se define usando la palabra reservada `trait`. -```tut +```scala mdoc:nest trait Greeter { def greet(name: String): Unit } @@ -280,7 +280,7 @@ trait Greeter { Un `trait` también puede definir un método, o un valor, con una implementación por defecto. {% scalafiddle %} -```tut +```scala mdoc:reset trait Greeter { def greet(name: String): Unit = println("Hello, " + name + "!") @@ -289,7 +289,7 @@ trait Greeter { Un `trait` también puede extender otros traits, usando la palabra clave `extends`. Asimismo, en un `trait` se puede redefinir la implementación de un método heredado, usando la palabra reservada `override`. -```tut +```scala mdoc class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { @@ -316,7 +316,7 @@ El método principal (main) es el punto donde comienza la ejecución de un progr Usando un objeto, puedes definir el método principal de la siguiente forma: -```tut +```scala mdoc object Main { def main(args: Array[String]): Unit = println("Hello, Scala developer!") diff --git a/_es/tour/multiple-parameter-lists.md b/_es/tour/multiple-parameter-lists.md index 79d2318e3e..9ed0531042 100644 --- a/_es/tour/multiple-parameter-lists.md +++ b/_es/tour/multiple-parameter-lists.md @@ -18,7 +18,7 @@ Los métodos pueden definir múltiples listas de parámetros. Cuando un método A continuación hay un ejemplo, tal y como se define en el trait `TraversableOnce` en el API de colecciones de Scala: -``` +```scala mdoc:fail def foldLeft[B](z: B)(op: (B, A) => B): B ``` @@ -27,7 +27,7 @@ def foldLeft[B](z: B)(op: (B, A) => B): B Comenzando con un valor inicial 0, `foldLeft` aplica la función `(m, n) => m + n` a cada uno de los elementos de la lista y al valor acumulado previo. {% scalafiddle %} -```tut +```scala mdoc val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val res = numbers.foldLeft(0)((m, n) => m + n) println(res) // 55 @@ -38,7 +38,7 @@ println(res) // 55 A continuación se muestra otro ejemplo: {% scalafiddle %} -```tut +```scala mdoc object CurryTest extends App { def filter(xs: List[Int], p: Int => Boolean): List[Int] = @@ -59,9 +59,10 @@ _Nota: el método `modN` está parcialmente aplicado en las dos llamadas a `filt Aquí se muestra la salida del programa anterior: - List(2,4,6,8) - List(3,6) - +```scala mdoc +List(2,4,6,8) +List(3,6) +``` ### Casos de uso @@ -72,19 +73,19 @@ Casos de uso sugeridos para múltiples listas de parámetros incluyen: En Scala, la inferencia de tipos se realiza parámetro a parámetro. Suponer que se dispone del siguiente método: -```tut +```scala mdoc def foldLeft1[A, B](as: List[A], b0: B, op: (B, A) => B) = ??? ``` Si se invoca de la siguiente manera, se puede comprobar que no compila correctamente: -```tut:fail +```scala mdoc:fail def notPossible = foldLeft1(numbers, 0, _ + _) ``` Debes invocarlo de alguna de las maneras propuestas a continuación: -```tut +```scala mdoc def firstWay = foldLeft1[Int, Int](numbers, 0, _ + _) def secondWay = foldLeft1(numbers, 0, (a: Int, b: Int) => a + b) ``` @@ -93,7 +94,7 @@ Esto se debe a que Scala no será capaz de inferir el tipo de la función `_ + _ Moviéndo el parámetro `op` a su propia lista de parámetros, los tipos de `A` y `B` son inferidos en la primera lista de parámetros. Una vez se han inferido sus tipos, estos están disponibles para la segunda lista de parámetros y `_ + _ ` podrá casar con los tipos inferidos `(Int, Int) => Int` -```tut +```scala mdoc def foldLeft2[A, B](as: List[A], b0: B)(op: (B, A) => B) = ??? def possible = foldLeft2(numbers, 0)(_ + _) ``` @@ -107,7 +108,7 @@ Para especificar solamente ciertos parámetros como [`implicit`](https://docs.sc Un ejemplo de esto se muestra a continuación: -``` +```scala mdoc def execute(arg: Int)(implicit ec: scala.concurrent.ExecutionContext) = ??? ``` @@ -117,7 +118,7 @@ Cuando un método es invocado con menos parámetros que los que están declarado Por ejemplo, -```tut +```scala mdoc:nest val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val numberFunc = numbers.foldLeft(List[Int]()) _ diff --git a/_es/tour/tuples.md b/_es/tour/tuples.md index 004b06beac..27ba0d9819 100644 --- a/_es/tour/tuples.md +++ b/_es/tour/tuples.md @@ -18,7 +18,7 @@ un método. Una tupla con dos elementos puede ser creada del siguiente modo: -```tut +```scala mdoc val ingredient = ("Sugar", 25) ``` @@ -37,7 +37,7 @@ Cada clase tiene tantos parámetros como número de elementos. Una forma de acceder a los elementos de una tupla es por posición. Los elementos concretos se llaman `_1`, `_2`, y así sucesivamente. -```tut +```scala mdoc println(ingredient._1) // Sugar println(ingredient._2) // 25 ``` @@ -46,7 +46,7 @@ println(ingredient._2) // 25 Una tupla también puede ser dividida/expandida usando reconocimiento de patrones (pattern matching): -```tut +```scala mdoc val (name, quantity) = ingredient println(name) // Sugar println(quantity) // 25 @@ -57,7 +57,7 @@ En esta ocasión el tipo de `name` es inferido como `String` y el de A continuación otro ejemplo de reconocimiento de patrones con tuplas: -```tut +```scala mdoc val planets = List(("Mercury", 57.9), ("Venus", 108.2), ("Earth", 149.6), ("Mars", 227.9), ("Jupiter", 778.3)) @@ -70,7 +70,7 @@ planets.foreach{ O en compresión de bucles `for`: -```tut +```scala mdoc val numPairs = List((2, 5), (3, -7), (20, 56)) for ((a, b) <- numPairs) { println(a * b) diff --git a/_es/tour/variances.md b/_es/tour/variances.md index feedee8fbb..eb961061a8 100644 --- a/_es/tour/variances.md +++ b/_es/tour/variances.md @@ -14,7 +14,7 @@ Scala soporta anotaciones de varianza para parámetros de tipo para [clases gen En el artículo sobre clases genéricas dimos un ejemplo de una pila mutable. Explicamos que el tipo definido por la clase `Stack[T]` es objeto de subtipos invariantes con respecto al parámetro de tipo. Esto puede restringir el reuso de la abstracción (la clase). Ahora derivaremos una implementación funcional (es decir, inmutable) para pilas que no tienen esta restricción. Nótese que este es un ejemplo avanzado que combina el uso de [métodos polimórficos](polymorphic-methods.html), [límites de tipado inferiores](lower-type-bounds.html), y anotaciones de parámetros de tipo covariante de una forma no trivial. Además hacemos uso de [clases internas](inner-classes.html) para encadenar los elementos de la pila sin enlaces explícitos. -```tut +```scala mdoc class Stack[+T] { def push[S >: T](elem: S): Stack[S] = new Stack[S] { override def top: S = elem diff --git a/_fr/tour/basics.md b/_fr/tour/basics.md index d30be44941..a16e3c7970 100644 --- a/_fr/tour/basics.md +++ b/_fr/tour/basics.md @@ -8,4 +8,4 @@ language: fr next-page: unified-types previous-page: tour-of-scala ---- \ No newline at end of file +--- diff --git a/_fr/tour/classes.md b/_fr/tour/classes.md index 63480c2848..40f56d0513 100644 --- a/_fr/tour/classes.md +++ b/_fr/tour/classes.md @@ -9,4 +9,4 @@ language: fr next-page: traits previous-page: unified-types ---- \ No newline at end of file +--- diff --git a/_fr/tour/package-objects.md b/_fr/tour/package-objects.md index 9c1b78716d..80cfb5e055 100644 --- a/_fr/tour/package-objects.md +++ b/_fr/tour/package-objects.md @@ -6,4 +6,4 @@ partof: scala-tour num: 36 previous-page: packages-and-imports ---- \ No newline at end of file +--- diff --git a/_fr/tour/traits.md b/_fr/tour/traits.md index fb57d520aa..069648bb53 100644 --- a/_fr/tour/traits.md +++ b/_fr/tour/traits.md @@ -9,4 +9,4 @@ language: fr next-page: tuples previous-page: classes ---- \ No newline at end of file +--- diff --git a/_fr/tour/tuples.md b/_fr/tour/tuples.md index 74cd02ff85..c4c268f376 100644 --- a/_fr/tour/tuples.md +++ b/_fr/tour/tuples.md @@ -9,4 +9,4 @@ language: fr next-page: mixin-class-composition previous-page: traits ---- \ No newline at end of file +--- diff --git a/_fr/tour/unified-types.md b/_fr/tour/unified-types.md index d914ee3fd0..6ecf013319 100644 --- a/_fr/tour/unified-types.md +++ b/_fr/tour/unified-types.md @@ -9,4 +9,4 @@ language: fr next-page: classes previous-page: basics ---- \ No newline at end of file +--- diff --git a/_ja/tour/abstract-type-members.md b/_ja/tour/abstract-type-members.md index 0a0a61f387..2f480833bf 100644 --- a/_ja/tour/abstract-type-members.md +++ b/_ja/tour/abstract-type-members.md @@ -18,7 +18,7 @@ prerequisite-knowledge: variance, upper-type-bound これは具体的な実装で実際の型を定義するという意味です。 こちらが例です。 -```tut +```scala mdoc trait Buffer { type T val element: T @@ -26,7 +26,7 @@ trait Buffer { ``` こちらでは、抽象型`type T`を定義しています。それは`element`の型を記述するために使われます。このトレイトを抽象クラスで継承し、より具体的にするために上限型境界を`T`に追加することができます。 -```tut +```scala mdoc abstract class SeqBuffer extends Buffer { type U type T <: Seq[U] @@ -38,7 +38,7 @@ abstract class SeqBuffer extends Buffer { 抽象型メンバーを持つトレイトと[クラス](classes.html)は無名クラスのインスタンス化と組み合わせてよく使われます。 これを説明するために、今から整数のリストを参照するシーケンスバッファーを扱うプログラムを見てみます。 -```tut +```scala mdoc abstract class IntSeqBuffer extends SeqBuffer { type U = Int } @@ -57,7 +57,7 @@ println("content = " + buf.element) 抽象型メンバーをクラスの型パラメータに変えることも、その逆も可能です。以下は上記コードの型パラメータのみを使うバージョンです。 -```tut +```scala mdoc:nest abstract class Buffer[+T] { val element: T } diff --git a/_ja/tour/annotations.md b/_ja/tour/annotations.md index 7347894b70..d0fad2e82a 100644 --- a/_ja/tour/annotations.md +++ b/_ja/tour/annotations.md @@ -29,7 +29,7 @@ object DeprecationDemo extends App { ## エンコーディングの正確性を保証するアノテーション 条件が一致しない場合にコンパイルを失敗させるアノテーションもあります。例えば、アノテーション`@tailrec`はメソッドが[末尾再帰](https://en.wikipedia.org/wiki/Tail_call)であると保証します。末尾再帰ではメモリ使用量が一定になります。こちらは階乗を計算するメソッドの中での使われ方です。 -```tut +```scala mdoc import scala.annotation.tailrec def factorial(x: Int): Int = { diff --git a/_ja/tour/basics.md b/_ja/tour/basics.md index 669564483d..b2b06317bb 100644 --- a/_ja/tour/basics.md +++ b/_ja/tour/basics.md @@ -32,13 +32,13 @@ ScalaFiddleを利用することでブラウザ上でScalaを実行すること 式は計算可能な文です。 -``` +```scala mdoc 1 + 1 ``` `println`を使うことで、式の結果を出力できます。 {% scalafiddle %} -```tut +```scala mdoc println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! @@ -50,7 +50,7 @@ println("Hello," + " world!") // Hello, world! `val`キーワードを利用することで、式の結果に名前を付けることができます。 -```tut +```scala mdoc val x = 1 + 1 println(x) // 2 ``` @@ -60,13 +60,13 @@ println(x) // 2 値は再代入することができません。 -```tut:fail +```scala mdoc:fail x = 3 // この記述はコンパイルされません。 ``` 値の型は推測可能ですが、このように型を明示的に宣言することもできます。 -```tut +```scala mdoc:nest val x: Int = 1 + 1 ``` @@ -77,7 +77,7 @@ val x: Int = 1 + 1 再代入ができることを除けば、変数は値と似ています。 `var`キーワードを使うことで、変数は定義できます。 -```tut +```scala mdoc:nest var x = 1 + 1 x = 3 // "x"は"var"キーワードで宣言されているので、これはコンパイルされます。 println(x * x) // 9 @@ -85,7 +85,7 @@ println(x * x) // 9 値と同様に、型を宣言したければ、明示的に型を宣言することができます。 -```tut +```scala mdoc:nest var x: Int = 1 + 1 ``` @@ -96,7 +96,7 @@ var x: Int = 1 + 1 ブロックの最後の式の結果はブロック全体の結果にもなります。 -```tut +```scala mdoc println({ val x = 1 + 1 x + 1 @@ -108,7 +108,7 @@ println({ 関数はパラメーターを受け取る式です。 ここでは与えられた数値に1を足す無名関数(すなわち名前が無い関数)を宣言しています。 -```tut +```scala mdoc (x: Int) => x + 1 ``` `=>` の左側はパラメーターのリストです。右側はパラメーターを含む式です。 @@ -116,7 +116,7 @@ println({ 関数には名前をつけることもできます。 {% scalafiddle %} -```tut +```scala mdoc val addOne = (x: Int) => x + 1 println(addOne(1)) // 2 ``` @@ -125,7 +125,7 @@ println(addOne(1)) // 2 関数は複数のパラメーターをとることもできます。 {% scalafiddle %} -```tut +```scala mdoc val add = (x: Int, y: Int) => x + y println(add(1, 2)) // 3 ``` @@ -133,7 +133,7 @@ println(add(1, 2)) // 3 またパラメーターを取らないこともありえます。 -```tut +```scala mdoc val getTheAnswer = () => 42 println(getTheAnswer()) // 42 ``` @@ -145,7 +145,7 @@ println(getTheAnswer()) // 42 メソッドは `def` キーワードで定義されます。 `def` の後ろには名前、パラメーターリスト、戻り値の型、処理の内容が続きます。 {% scalafiddle %} -```tut +```scala mdoc:nest def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3 ``` @@ -156,7 +156,7 @@ println(add(1, 2)) // 3 メソッドは複数のパラメーターリストを受け取ることができます。 {% scalafiddle %} -```tut +```scala mdoc def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9 ``` @@ -164,7 +164,7 @@ println(addThenMultiply(1, 2)(3)) // 9 また、パラメーターリストを一切受け取らないこともあります。 -```tut +```scala mdoc def name: String = System.getProperty("user.name") println("Hello, " + name + "!") ``` @@ -173,7 +173,7 @@ println("Hello, " + name + "!") メソッドは複数行の式も持つことができます。 {% scalafiddle %} -```tut +```scala mdoc def getSquareString(input: Double): String = { val square = input * input square.toString @@ -188,7 +188,7 @@ println(getSquareString(2.5)) // 6.25 `class` キーワードとその後ろに名前、コンストラクタパラメーターを続けることで、クラスを定義することができます。 -```tut +```scala mdoc class Greeter(prefix: String, suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) @@ -200,7 +200,7 @@ class Greeter(prefix: String, suffix: String) { `new` キーワードを使うことで、クラスのインスタンスを生成することができます。 -```tut +```scala mdoc val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` @@ -212,12 +212,12 @@ greeter.greet("Scala developer") // Hello, Scala developer! Scalaには"ケース"クラスという特別な種類のクラスがあります。デフォルトでケースクラスは不変であり、値で比較されます。 `case class` キーワードを利用して、ケースクラスを定義できます。 -```tut +```scala mdoc case class Point(x: Int, y: Int) ``` ケースクラスは、`new` キーワードなしでインスタンス化できます。 -```tut +```scala mdoc val point = Point(1, 2) val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2) @@ -225,7 +225,7 @@ val yetAnotherPoint = Point(2, 2) ケースクラスは値で比較されます。 -```tut +```scala mdoc if (point == anotherPoint) { println(point + " と " + anotherPoint + " は同じです。") } else { @@ -248,7 +248,7 @@ if (point == yetAnotherPoint) { `object`キーワードを利用してオブジェクトを定義することができます。 -```tut +```scala mdoc object IdFactory { private var counter = 0 def create(): Int = { @@ -260,7 +260,7 @@ object IdFactory { 名前を参照してオブジェクトにアクセスすることができます。 -```tut +```scala mdoc val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() @@ -275,7 +275,7 @@ println(newerId) // 2 `trait`キーワードでトレイトを定義することができます。 -```tut +```scala mdoc:nest trait Greeter { def greet(name: String): Unit } @@ -284,7 +284,7 @@ trait Greeter { トレイトはデフォルトの実装を持つこともできます。 {% scalafiddle %} -```tut +```scala mdoc:reset trait Greeter { def greet(name: String): Unit = println("Hello, " + name + "!") @@ -293,7 +293,7 @@ trait Greeter { `extends`キーワードでトレイトを継承することも、`override` キーワードで実装をオーバーライドすることもできます。 -```tut +```scala mdoc class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { @@ -321,7 +321,7 @@ customGreeter.greet("Scala developer") // How are you, Scala developer? オブジェクトを使い、以下のようにメインメソッドを定義することができます。 -```tut +```scala mdoc object Main { def main(args: Array[String]): Unit = println("Hello, Scala developer!") diff --git a/_ja/tour/by-name-parameters.md b/_ja/tour/by-name-parameters.md index 411afa5957..c3494f5634 100644 --- a/_ja/tour/by-name-parameters.md +++ b/_ja/tour/by-name-parameters.md @@ -14,7 +14,7 @@ previous-page: operators --- *名前渡しのパラメータ*は使用された時に評価されます。それらは*値渡しパラメータ*とは対照的です。名前渡しのパラメータを作るには、単純に`=>`を型の前につけます。 -```tut +```scala mdoc def calculate(input: => Int) = input * 37 ``` @@ -22,7 +22,7 @@ def calculate(input: => Int) = input * 37 こちらはwhileループをどのように実装するかの例です。 -```tut +```scala mdoc def whileLoop(condition: => Boolean)(body: => Unit): Unit = if (condition) { body diff --git a/_ja/tour/case-classes.md b/_ja/tour/case-classes.md index 5493a00790..65cce59c9b 100644 --- a/_ja/tour/case-classes.md +++ b/_ja/tour/case-classes.md @@ -21,7 +21,7 @@ prerequisite-knowledge: classes, basics, mutability ## ケースクラスの宣言 最小のケースクラスにはキーワード`case class`、識別子、パラメータリスト(空かもしれません)が必要です。 -```tut +```scala mdoc case class Book(isbn: String) val frankenstein = Book("978-0486282114") diff --git a/_ja/tour/classes.md b/_ja/tour/classes.md index 36cf3ec851..7fdaea722d 100644 --- a/_ja/tour/classes.md +++ b/_ja/tour/classes.md @@ -24,7 +24,7 @@ Scalaにおけるクラスはオブジェクトを作るための設計図です 最小のクラス定義は単純にキーワード`class`と識別子だけというものです。 クラス名は大文字から始まるべきです。 -```tut +```scala mdoc class User val user1 = new User @@ -34,7 +34,7 @@ val user1 = new User しかしながら、コンストラクターとクラス本体は頻繁に欲しくなるでしょう。 こちらは位置情報のクラス定義の例になります。 -```tut +```scala mdoc class Point(var x: Int, var y: Int) { def move(dx: Int, dy: Int): Unit = { @@ -62,7 +62,7 @@ println(point1) // prints (2, 3) コンストラクターは次のようにデフォルト値を与えると省略可能なパラメーターを持つことができます。 -```tut +```scala mdoc:reset class Point(var x: Int = 0, var y: Int = 0) val origin = new Point // x と y には共に0がセットされます。 @@ -72,7 +72,7 @@ println(point1.x) // 1 が出力されます。 このバージョンの`Point`クラスでは、`x` と `y` はデフォルト値0を持ち、引数が必須ではありません。 しかしながらコンストラクタは引数を左から右に読み込むため、もし`y`の値だけを渡したい場合は、パラメーターに名前をつける必要があります。 -``` +```scala mdoc:reset class Point(var x: Int = 0, var y: Int = 0) val point2 = new Point(y=2) println(point2.y) // 2 が出力されます。 @@ -84,7 +84,7 @@ println(point2.y) // 2 が出力されます。 メンバーはデフォルトではパブリックになります。 クラスの外から隠したい場合は`private`アクセス修飾詞を使いましょう。 -```tut +```scala mdoc:reset class Point { private var _x = 0 private var _y = 0 @@ -116,14 +116,15 @@ point1.y = 101 // 警告が出力されます。 プライマリコンストラクタの`val` と `var` を持つパラメーターはパブリックになります。 しかしながら`val` は不変となるため、以下のように記述することはできません。 -``` +```scala mdoc:fail class Point(val x: Int, val y: Int) val point = new Point(1, 2) point.x = 3 // <-- コンパイルされません。 ``` `val` や `var` が存在しないパラメーターはクラス内でだけで参照できるプライベートな値や変数となります。 -``` + +```scala mdoc:fail class Point(x: Int, y: Int) val point = new Point(1, 2) point.x // <-- コンパイルされません。 diff --git a/_ja/tour/compound-types.md b/_ja/tour/compound-types.md index 061a5dc331..60be4af3c3 100644 --- a/_ja/tour/compound-types.md +++ b/_ja/tour/compound-types.md @@ -17,7 +17,7 @@ Scalaでは、これは*複合型*を用いて表現できます。複合型と 2つのトレイト`Cloneable`と`Resetable`があるとしましょう。 -```tut +```scala mdoc trait Cloneable extends java.lang.Cloneable { override def clone(): Cloneable = { super.clone().asInstanceOf[Cloneable] diff --git a/_ja/tour/default-parameter-values.md b/_ja/tour/default-parameter-values.md index dde76cdeaf..1e03cebe50 100644 --- a/_ja/tour/default-parameter-values.md +++ b/_ja/tour/default-parameter-values.md @@ -16,7 +16,7 @@ prerequisite-knowledge: named-arguments, function syntax Scalaはパラメータのデフォルト値を与えることができ、呼び出す側はこれらのパラメータを省略できます。 -```tut +```scala mdoc def log(message: String, level: String = "INFO") = println(s"$level: $message") log("System starting") // prints INFO: System starting @@ -25,7 +25,7 @@ log("User not found", "WARNING") // prints WARNING: User not found パラメータ`level`はデフォルト値を持つので、省略可能です。最終行では、引数`"WARNING"`はデフォルト値`"INFO"`を上書きします。Javaで同じ効果を得るのに、省略可能なパラメータをもつメソッドを複数使ってメソッドのオーバーロードをしたようなものです。しかしながら呼び出す側が引数をひとつ省略すると、以降全ての引数は名前つきにする必要があります。 -```tut +```scala mdoc class Point(val x: Double = 0, val y: Double = 0) val point1 = new Point(y = 1) @@ -34,7 +34,7 @@ val point1 = new Point(y = 1) Scalaで定義したデフォルトパラメータはJavaのコードから呼び出される時はオプショナルではありません。 -```tut +```scala mdoc:reset // Point.scala class Point(val x: Double = 0, val y: Double = 0) ``` diff --git a/_ja/tour/extractor-objects.md b/_ja/tour/extractor-objects.md index d3af5a18e7..8b0cf87797 100644 --- a/_ja/tour/extractor-objects.md +++ b/_ja/tour/extractor-objects.md @@ -17,7 +17,7 @@ previous-page: regular-expression-patterns `apply`メソッドが引数を取り、オブジェクトを作るコンストラクタであるように、`unapply`は1つのオブジェクトを受け取り、引数を返そうとします。 これはパターンマッチングと部分関数で最も頻繁に使われます。 -```tut +```scala mdoc import scala.util.Random object CustomerID { @@ -43,19 +43,19 @@ customer1ID match { 値を定義する文で、パターン中に新しい変数を使うことができるので、抽出子は変数を初期化するのに使えます。この場合unapplyメソッドが初期値を与えます。 -```tut +```scala mdoc val customer2ID = CustomerID("Nico") val CustomerID(name) = customer2ID println(name) // prints Nico ``` これは `val name = CustomerID.unapply(customer2ID).get`.と同じです。 -```tut +```scala mdoc val CustomerID(name2) = "--asdfasdfasdf" ``` もし一致しない場合`scala.MatchError`が投げられます。 -```tut:fail +```scala mdoc:crash val CustomerID(name3) = "-asdfasdfasdf" ``` diff --git a/_ja/tour/for-comprehensions.md b/_ja/tour/for-comprehensions.md index eccd124c8c..c673135b2b 100644 --- a/_ja/tour/for-comprehensions.md +++ b/_ja/tour/for-comprehensions.md @@ -20,7 +20,7 @@ Scalaは*シーケンス内包表記*を表現するための軽量な記法を こちらは例です。 -```tut +```scala mdoc case class User(name: String, age: Int) val userBase = List(User("Travis", 28), @@ -40,7 +40,7 @@ twentySomethings.foreach(name => println(name)) // prints Travis Dennis こちらは2つのジェネレータを使ったより複雑な例です。 合計が与えられた値`v`と等しくなる、`0`から`n-1`の全てのペアを計算します。 -```tut +```scala mdoc def foo(n: Int, v: Int) = for (i <- 0 until n; j <- 0 until n if i + j == v) @@ -66,7 +66,7 @@ foo(10, 10) foreach { これは副作用をもたらす必要があるときに役立ちます。 こちらは先に出たプログラムと同等のものですが、`yield`を使っていません。 -```tut +```scala mdoc:nest def foo(n: Int, v: Int) = for (i <- 0 until n; j <- 0 until n if i + j == v) diff --git a/_ja/tour/generic-classes.md b/_ja/tour/generic-classes.md index 8e04bacd92..148ae5013c 100644 --- a/_ja/tour/generic-classes.md +++ b/_ja/tour/generic-classes.md @@ -18,7 +18,7 @@ assumed-knowledge: classes unified-types ## ジェネリッククラスの定義 ジェネリッククラスは角カッコ`[]`の中にパラメータとして型を1つ受け取ります。 型パラメータの識別子として文字`A`を使う習慣がありますが、任意のパラメータ名を使うことができます。 -```tut +```scala mdoc class Stack[A] { private var elements: List[A] = Nil def push(x: A) { elements = x :: elements } diff --git a/_ja/tour/higher-order-functions.md b/_ja/tour/higher-order-functions.md index 88d432aaf5..73305802ee 100644 --- a/_ja/tour/higher-order-functions.md +++ b/_ja/tour/higher-order-functions.md @@ -19,7 +19,7 @@ previous-page: mixin-class-composition ここでは"高階関数"というフレーズを関数をパラメーターとして受け取る、または関数を返すメソッドと関数の両方に対して使います。 もっとも一般的な例の1つは、Scalaのコレクションで利用可能な高階関数`map`です。 -```tut +```scala mdoc val salaries = Seq(20000, 70000, 40000) val doubleSalary = (x: Int) => x * 2 val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000) @@ -29,7 +29,7 @@ val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000) 3行目で、給与のリストのそれぞれの値に`doubleSalary`が適用されます。 コードを減らすため、以下のように無名関数を作ることができ、引数として直接mapに渡すことができます -``` +```scala mdoc:nest val salaries = Seq(20000, 70000, 40000) val newSalaries = salaries.map(x => x * 2) // List(40000, 140000, 80000) ``` @@ -37,7 +37,7 @@ val newSalaries = salaries.map(x => x * 2) // List(40000, 140000, 80000) それはmap関数が期待する型を基にコンパイラーが型を推論できるからです。 さらに言えば、慣用的には同じコードを以下のように書きます。 -```tut +```scala mdoc:nest val salaries = Seq(20000, 70000, 40000) val newSalaries = salaries.map(_ * 2) ``` @@ -46,7 +46,7 @@ Scalaコンパイラはパラメーターの型を(Intが1つだけと)既 ## メソッドを関数に強制変換 高階関数には引数としてとしてメソッドを渡すことも可能で、それはScalaコンパイラがメソッドを関数に強制変換するからです。 -``` +```scala mdoc case class WeeklyWeatherForecast(temperatures: Seq[Double]) { private def convertCtoF(temp: Double) = temp * 1.8 + 32 @@ -62,7 +62,7 @@ case class WeeklyWeatherForecast(temperatures: Seq[Double]) { たとえば、何通りかの係数で人の給料を上げるメソッドが欲しいとしましょう。 高階関数を作らないなら、こんな感じになるかもしれません。 -```tut +```scala mdoc object SalaryRaiser { def smallPromotion(salaries: List[Double]): List[Double] = @@ -79,7 +79,7 @@ object SalaryRaiser { 3つのメソッドはそれぞれ掛け算の係数のみ異なることに気をつけてください。 簡潔にするため、以下のように繰り返されているコードを高階関数に抽出することができます。 -```tut +```scala mdoc:nest object SalaryRaiser { private def promotion(salaries: List[Double], promotionFunction: Double => Double): List[Double] = @@ -102,7 +102,7 @@ object SalaryRaiser { 関数を生成したい場合がいくつかあります。 こちらは関数を返すメソッドの例になります。 -```tut +```scala mdoc def urlBuilder(ssl: Boolean, domainName: String): (String, String) => String = { val schema = if (ssl) "https://" else "http://" (endpoint: String, query: String) => s"$schema$domainName/$endpoint?$query" diff --git a/_ja/tour/implicit-conversions.md b/_ja/tour/implicit-conversions.md index 107979e2dc..634dabcfca 100644 --- a/_ja/tour/implicit-conversions.md +++ b/_ja/tour/implicit-conversions.md @@ -30,7 +30,7 @@ List(1, 2, 3) <= List(4, 5) ``` implicitなメソッド`Int => Ordered[Int]`は`scala.Predef.intWrapper`を通じて自動的に提供されます。implicitなメソッドの例`List[A] => Ordered[List[A]]`は以下にあります。 -```tut +```scala mdoc import scala.language.implicitConversions implicit def list2ordered[A](x: List[A]) @@ -44,7 +44,7 @@ implicit def list2ordered[A](x: List[A]) 例えば、`java.lang.Integer`を受け取るようなJavaのメソッドを呼び出す時、自由に`scala.Int`を代わりに渡すことができます。それはPredefオブジェクトが以下の暗黙の変換をを含んでいるからです。 -```tut +```scala mdoc import scala.language.implicitConversions implicit def int2Integer(x: Int) = diff --git a/_ja/tour/implicit-parameters.md b/_ja/tour/implicit-parameters.md index 53613be8ee..30ff6028df 100644 --- a/_ja/tour/implicit-parameters.md +++ b/_ja/tour/implicit-parameters.md @@ -26,7 +26,7 @@ Scalaがimplicitをどこから見つけるかについてのより詳しいガ 以下の例では、モノイドの`add`と`unit`の演算を使い、要素のリストの合計を計算するメソッド`sum`を定義しています。 implicitの値をトップレベルには置けないことに注意してください。 -```tut +```scala mdoc abstract class Monoid[A] { def add(x: A, y: A): A def unit: A diff --git a/_ja/tour/inner-classes.md b/_ja/tour/inner-classes.md index 4745d445aa..5d38b1f1f6 100644 --- a/_ja/tour/inner-classes.md +++ b/_ja/tour/inner-classes.md @@ -20,7 +20,7 @@ Javaのような、内部クラスが外側のクラスのメンバーとなる その違いを示すために、グラフデータ型の実装をさっと書きます。 -```tut +```scala mdoc class Graph { class Node { var connectedNodes: List[Node] = Nil @@ -41,7 +41,7 @@ class Graph { このプログラムはグラフをノードのリスト(`List[Node]`)で表現しています。いずれのノードも接続している他のノードへのリスト(`connectedNodes`)を保持します。`class Node`は `class Graph`の中にネストしているので、 _パス依存型_ です。 そのため`connectedNodes`の中にある全てのノードは同じ`Graph`インスタンスから`newNode`を使用して作る必要があります。 -```tut +```scala mdoc val graph1: Graph = new Graph val node1: graph1.Node = graph1.newNode val node2: graph1.Node = graph1.newNode @@ -56,7 +56,7 @@ node3.connectTo(node1) それは別のグラフのノードは別の型を持つからです。 こちらは不正なプログラムです。 -``` +```scala mdoc:fail val graph1: Graph = new Graph val node1: graph1.Node = graph1.newNode val node2: graph1.Node = graph1.newNode @@ -70,7 +70,7 @@ node1.connectTo(node3) // illegal! Scalaではそのような型も同様に表現することができ、`Graph#Node`と書きます。 もし他のグラフのノードに接続できるようにしたければ、以下の方法で最初のグラフ実装の定義を変える必要があります。 -```tut +```scala mdoc:nest class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil diff --git a/_ja/tour/lower-type-bounds.md b/_ja/tour/lower-type-bounds.md index e522216a76..62a15447d3 100644 --- a/_ja/tour/lower-type-bounds.md +++ b/_ja/tour/lower-type-bounds.md @@ -18,7 +18,7 @@ prerequisite-knowledge: upper-type-bounds, generics, variance 以下はこれが役立つ場合の例です。 -```tut:fail +```scala mdoc:fail trait Node[+B] { def prepend(elem: B): Node[B] } @@ -44,7 +44,7 @@ case class Nil[+B]() extends Node[B] { これを解決するためには、`prepend`のパラメータ`elem`の型の変位指定を逆転させる必要があります。 これを実現するには、下限型境界として`B`を持つ新しい型パラメータ`U`を導入します。 -```tut +```scala mdoc trait Node[+B] { def prepend[U >: B](elem: U): Node[U] } @@ -61,7 +61,7 @@ case class Nil[+B]() extends Node[B] { ``` すると、以下のようなことができます。 -```tut +```scala mdoc trait Bird case class AfricanSwallow() extends Bird case class EuropeanSwallow() extends Bird diff --git a/_ja/tour/mixin-class-composition.md b/_ja/tour/mixin-class-composition.md index c5d40ebe16..8b4e26067e 100644 --- a/_ja/tour/mixin-class-composition.md +++ b/_ja/tour/mixin-class-composition.md @@ -15,7 +15,7 @@ prerequisite-knowledge: inheritance, traits, abstract-classes, unified-types --- ミックスインはクラスを構成するのに使われるトレイトです。 -```tut +```scala mdoc abstract class A { val message: String } @@ -37,7 +37,7 @@ println(d.loudMessage) // I'M AN INSTANCE OF CLASS B それでは抽象クラスから始まる興味深い例を見てみましょう。 -```tut +```scala mdoc abstract class AbsIterator { type T def hasNext: Boolean @@ -47,7 +47,7 @@ abstract class AbsIterator { クラスは抽象型`T`と標準的なイテレーターのメソッドを持ちます。 次に、(全ての抽象メンバー`T`, `hasNext`, `next`が実装を持つ)具象クラスを実装します。 -```tut +```scala mdoc class StringIterator(s: String) extends AbsIterator { type T = Char private var i = 0 @@ -64,7 +64,7 @@ class StringIterator(s: String) extends AbsIterator { それでは`AbsIterator`を継承したトレイトも作ってみましょう。 -```tut +```scala mdoc trait RichIterator extends AbsIterator { def foreach(f: T => Unit): Unit = while (hasNext) f(next()) } @@ -73,7 +73,7 @@ trait RichIterator extends AbsIterator { `RichIterator`はトレイトなので、`RichIterator`はAbsIteratorの抽象メンバーを実装する必要がありません。 `StringIterator`と`RichIterator`の機能を1つのクラスに組み合わせてみましょう。 -```tut +```scala mdoc class RichStringIter extends StringIterator("Scala") with RichIterator val richStringIter = new RichStringIter richStringIter foreach println diff --git a/_ja/tour/multiple-parameter-lists.md b/_ja/tour/multiple-parameter-lists.md index 3cddffe859..ff267531b8 100644 --- a/_ja/tour/multiple-parameter-lists.md +++ b/_ja/tour/multiple-parameter-lists.md @@ -19,7 +19,7 @@ previous-page: nested-functions こちらはScalaのコレクションAPIの `TraversableOnce`トレイトで定義されている実例です。 -``` +```scala mdoc:fail def foldLeft[B](z: B)(op: (B, A) => B): B ``` `foldLeft`は、2つのパラメータを取る関数`op`を、初期値`z`とこのコレクションの全要素に対して左から右に適用していきます。 @@ -28,7 +28,7 @@ def foldLeft[B](z: B)(op: (B, A) => B): B 初期値0から始まり、`foldLeft`はここではリスト内の各要素とその一つ前の累積値に関数`(m, n) => m + n`を適用します。 {% scalafiddle %} -```tut +```scala mdoc val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val res = numbers.foldLeft(0)((m, n) => m + n) println(res) // 55 @@ -43,13 +43,13 @@ println(res) // 55 複数パラメータリストがない場合、このコードは以下のようになります。 -``` +```scala mdoc:fail numbers.foldLeft(0, (m: Int, n: Int) => m + n) ``` 複数パラメータリストを使うことで、Scalaの型インターフェースの利点を享受でき、以下のようにコードをより簡潔にすることができるのです。 -``` +```scala mdoc numbers.foldLeft(0)(_ + _) ``` 単一のパラメータリストではScalaコンパイラが関数のパラメータを型推論できないので、このようなことはできません。 @@ -58,7 +58,7 @@ numbers.foldLeft(0)(_ + _) 特定のパラメータだけを`implicit`として指定するには、`implicit`のパラメーターリストに入れなければなりません。 こちらが例です。 -``` +```scala mdoc def execute(arg: Int)(implicit ec: scala.concurrent.ExecutionContext) = ??? ``` @@ -68,7 +68,7 @@ def execute(arg: Int)(implicit ec: scala.concurrent.ExecutionContext) = ??? これは一般的に[部分適用](https://en.wikipedia.org/wiki/Partial_application)として知られています。 例えば -```tut +```scala mdoc:nest val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val numberFunc = numbers.foldLeft(List[Int]()) _ val squares = numberFunc((xs, x) => xs :+ x*x) diff --git a/_ja/tour/named-arguments.md b/_ja/tour/named-arguments.md index eda94a0c8c..8ce70335a9 100644 --- a/_ja/tour/named-arguments.md +++ b/_ja/tour/named-arguments.md @@ -16,7 +16,7 @@ prerequisite-knowledge: function-syntax メソッドを呼ぶ時、以下のように引数にパラメータ名でラベル付が可能です。 -```tut +```scala mdoc def printName(first: String, last: String): Unit = { println(first + " " + last) } @@ -28,7 +28,7 @@ printName(last = "Smith", first = "John") // Prints "John Smith" 名前付き引数の順序はどのように並び替えられるかに気をつけましょう。ただし、名前つき引数と名前つきでない引数がある場合は、名前つきでない引数は引数リストの最初に置かれ、かつメソッドシグネチャのパラメーター順でなければなりません。 -```tut:fail +```scala mdoc:fail printName(last = "Smith", "john") // error: positional after named argument ``` diff --git a/_ja/tour/nested-functions.md b/_ja/tour/nested-functions.md index 2769c20674..9701e421cc 100644 --- a/_ja/tour/nested-functions.md +++ b/_ja/tour/nested-functions.md @@ -17,7 +17,7 @@ Scalaではメソッドの定義をネストする(_訳注:入れ子にす 以下のコードは与えられた数値の階乗を計算するための`factorial`メソッドを提供します。 {% scalafiddle %} -```tut +```scala mdoc def factorial(x: Int): Int = { def fact(x: Int, accumulator: Int): Int = { if (x <= 1) accumulator diff --git a/_ja/tour/operators.md b/_ja/tour/operators.md index f5b1ac6ed5..0b13e639bd 100644 --- a/_ja/tour/operators.md +++ b/_ja/tour/operators.md @@ -28,7 +28,7 @@ Scalaでは演算子はメソッドです。パラメータを1つだけ持つ ## 演算子の定義方法と使い方 有効な識別子であれば演算子として使用できます。これは `add`のような名前も`+`のような記号も含みます。 -```tut +```scala mdoc case class Vec(x: Double, y: Double) { def +(that: Vec) = Vec(this.x + that.x, this.y + that.y) } @@ -43,7 +43,7 @@ vector3.y // 3.0 クラスVecはメソッド`+`を持ち、 `vector1`と`vector2`を足しわせるのに使います。丸括弧を用いて、複雑な式を読みやすい構文で作ることができます。 こちらはクラス`MyBool`の定義です。クラス`MyBool`はメソッド`and`と`or`を含みます。 -```tut +```scala mdoc case class MyBool(x: Boolean) { def and(that: MyBool): MyBool = if (x) that else this def or(that: MyBool): MyBool = if (x) this else that @@ -53,7 +53,7 @@ case class MyBool(x: Boolean) { この時、`and`と`or`を中置演算子として使えます。 -```tut +```scala mdoc def not(x: MyBool) = x.negate def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y) ``` diff --git a/_ja/tour/packages-and-imports.md b/_ja/tour/packages-and-imports.md index dd2e42f844..8e44239b05 100644 --- a/_ja/tour/packages-and-imports.md +++ b/_ja/tour/packages-and-imports.md @@ -70,7 +70,7 @@ import users.{UserPreferences => UPrefs} // インポートし利便性のた ``` ScalaのJavaと異なる点の1つはインポートがどこでも使える点です。 -```tut +```scala mdoc def sqrtplus1(x: Int) = { import scala.math.sqrt sqrt(x) + 1.0 diff --git a/_ja/tour/pattern-matching.md b/_ja/tour/pattern-matching.md index f5d506bdf4..9e1f5d9692 100644 --- a/_ja/tour/pattern-matching.md +++ b/_ja/tour/pattern-matching.md @@ -22,7 +22,7 @@ Javaの`switch`文の強化バージョンで、if/else文の連続の代わり ## 構文 マッチ式は値、キーワード`match`と少なくとも1つの`case`句を持ちます。 -```tut +```scala mdoc import scala.util.Random val x: Int = Random.nextInt(10) @@ -39,7 +39,7 @@ x match { ケースは*オルタナティブ*とも呼ばれます。 マッチ式は値を持ちます。 -```tut +```scala mdoc def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" @@ -55,7 +55,7 @@ matchTest(1) // one ケースクラスはパターンマッチングで特に役立ちます。 -```tut +```scala mdoc abstract class Notification case class Email(sender: String, title: String, body: String) extends Notification @@ -124,7 +124,7 @@ println(showImportantNotification(importantSms, importantPeopleInfo)) ## 型のみでのマッチング 以下のように型のみでマッチすることができます。 -```tut +```scala mdoc abstract class Device case class Phone(model: String) extends Device { def screenOff = "Turning screen off" @@ -146,7 +146,7 @@ def goIdle(device: Device) = device match { トレイトとクラスに`sealed`をつけると、全てのサブタイプは同一ファイル内で宣言されなければならないという意味になります。 これは全てのサブタイプが既知であることを保証します。 -```tut +```scala mdoc sealed abstract class Furniture case class Couch() extends Furniture case class Chair() extends Furniture diff --git a/_ja/tour/polymorphic-methods.md b/_ja/tour/polymorphic-methods.md index 7eac75ff39..6143ef2612 100644 --- a/_ja/tour/polymorphic-methods.md +++ b/_ja/tour/polymorphic-methods.md @@ -20,7 +20,7 @@ Scalaのメソッドは値と同様に型によってパラメータ化するこ こちらが例です。 -```tut +```scala mdoc def listOfDuplicates[A](x: A, length: Int): List[A] = { if (length < 1) Nil diff --git a/_ja/tour/regular-expression-patterns.md b/_ja/tour/regular-expression-patterns.md index a81168544c..05882529c0 100644 --- a/_ja/tour/regular-expression-patterns.md +++ b/_ja/tour/regular-expression-patterns.md @@ -16,7 +16,7 @@ previous-page: singleton-objects 正規表現はデータの中からパターン(またはその欠如)を探すために使うことができる文字列です。 どんな文字列も`.r`メソッドを使うことで、正規表現に変換できます。 -```tut +```scala mdoc import scala.util.matching.Regex val numberPattern: Regex = "[0-9]".r @@ -30,7 +30,7 @@ numberPattern.findFirstMatchIn("awesomepassword") match { 括弧を使うことで、正規表現のグループを探すこともできます。 -```tut +```scala mdoc import scala.util.matching.Regex val keyValPattern: Regex = "([0-9a-zA-Z-#() ]+): ([0-9a-zA-Z-#() ]+)".r diff --git a/_ja/tour/self-types.md b/_ja/tour/self-types.md index 1bffbfe63c..103fa0d2c2 100644 --- a/_ja/tour/self-types.md +++ b/_ja/tour/self-types.md @@ -21,7 +21,7 @@ prerequisite-knowledge: nested-classes, mixin-class-composition その構文は普通の関数構文のように見えますが、全く異なる意味があります。 トレイトで自分型を使うには、識別子、ミックスインする他のトレイトの型、`=>`を書きます(例えば `someIdentifier: SomeOtherTrait =>`)。 -```tut +```scala mdoc trait User { def username: String } diff --git a/_ja/tour/singleton-objects.md b/_ja/tour/singleton-objects.md index 5681d92552..69ce1aeede 100644 --- a/_ja/tour/singleton-objects.md +++ b/_ja/tour/singleton-objects.md @@ -21,7 +21,7 @@ prerequisite-knowledge: classes, methods, private-methods, packages, option # シングルトンオブジェクトの定義 オブジェクトは値です。オブジェクトの定義はクラスのように見えますが、キーワード`object`を使います。 -```tut +```scala mdoc object Box ``` これはメソッドを持つオブジェクトの例です。 @@ -84,7 +84,7 @@ circle1.area `class Circle`は各インスタンスの固有のメンバー`area`を持ち、シングルトンオブジェクト`object Circle`は全てのインスタンスで利用できる`calculateArea`メソッドを持ちます。 コンパニオンオブジェクトはファクトリーメソッドを含むことができます。 -```tut +```scala mdoc class Email(val username: String, val domainName: String) object Email { diff --git a/_ja/tour/traits.md b/_ja/tour/traits.md index 5152af0fb0..887eed1741 100644 --- a/_ja/tour/traits.md +++ b/_ja/tour/traits.md @@ -21,12 +21,12 @@ prerequisite-knowledge: expressions, classes, generics, objects, companion-objec ## トレイトを定義する 最小のトレイトはキーワード `trait` と識別子だけというものです。 -```tut +```scala mdoc trait HairColor ``` トレイトはジェネリック型として、抽象メソッドとあわせて使うと特に便利です。 -```tut +```scala mdoc trait Iterator[A] { def hasNext: Boolean def next(): A @@ -37,7 +37,7 @@ trait Iterator[A] { ## トレイトの使い方 トレイトを継承するには `extends` キーワードを使います。その際に、 `override` キーワードを利用しすべての抽象メンバーを実装します。 -```tut +```scala mdoc:nest trait Iterator[A] { def hasNext: Boolean def next(): A @@ -66,7 +66,7 @@ iterator.next() // returns 1 ## サブタイピング あるトレイトが必要とされている場所に、代りにそのトレイトのサブタイプを使うことができます。 -```tut +```scala mdoc import scala.collection.mutable.ArrayBuffer trait Pet { diff --git a/_ja/tour/tuples.md b/_ja/tour/tuples.md index 822a6f5a72..7729138914 100644 --- a/_ja/tour/tuples.md +++ b/_ja/tour/tuples.md @@ -21,7 +21,7 @@ Scalaではタプルは決まった数の要素を含む値であり、各要素 2つの要素を持つタプルは以下のように作ることができます。 -```tut +```scala mdoc val ingredient = ("Sugar" , 25) ``` ここでは`String`要素を1つと`Int`要素を1つ含むタプルを作っています。 @@ -36,14 +36,14 @@ val ingredient = ("Sugar" , 25) タプルの要素へのアクセス方法の1つとして、位置があります。 個々の要素は`_1`、`_2`などと名付けられます。 -```tut +```scala mdoc println(ingredient._1) // Sugar println(ingredient._2) // 25 ``` ## タプルでのパターンマッチング タプルはパターンマッチングを使って分解することもできます。 -```tut +```scala mdoc val (name, quantity) = ingredient println(name) // Sugar println(quantity) // 25 @@ -53,7 +53,7 @@ println(quantity) // 25 こちらはタプルのパターンマッチングの他の例です。 -```tut +```scala mdoc val planets = List(("Mercury", 57.9), ("Venus", 108.2), ("Earth", 149.6), ("Mars", 227.9), ("Jupiter", 778.3)) @@ -66,7 +66,7 @@ planets.foreach{ また、`for`内包表記では以下のようになります。 -```tut +```scala mdoc val numPairs = List((2, 5), (3, -7), (20, 56)) for ((a, b) <- numPairs) { println(a * b) diff --git a/_ja/tour/type-inference.md b/_ja/tour/type-inference.md index 3fb93ee339..4fafc6814f 100644 --- a/_ja/tour/type-inference.md +++ b/_ja/tour/type-inference.md @@ -16,19 +16,19 @@ Scalaコンパイラが式の型を推論できることが多いので、明示 ## 型の省略 -```tut +```scala mdoc val businessName = "Montreux Jazz Café" ``` コンパイラは`businessName`がStringだと検知できます。これはメソッドでも同様に動きます。 -```tut +```scala mdoc def squareOf(x: Int) = x * x ``` コンパイラは戻り値の型が`Int`だと推論できるので、明示的な戻り値の型は必要ありません。 再帰的メソッドでは、コンパイラは結果の型を推論できません。こちらはこの理由でコンパイラが失敗するプログラムです。 -```tut:fail +```scala mdoc:fail def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) ``` @@ -36,7 +36,7 @@ def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) こちらは2つの例です。 -```tut +```scala mdoc case class MyPair[A, B](x: A, y: B) val p = MyPair(1, "scala") // 型: MyPair[Int, String] @@ -49,7 +49,7 @@ val q = id(1) // 型: Int コンパイラはメソッドのパラメータ型を決して推論しません。しかし、関数が引数として渡されている場合は、無名関数のパラメータ型を推論できます。 -```tut +```scala mdoc Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) ``` @@ -61,13 +61,13 @@ mapのパラメータは`f: A => B`です。`Seq`の中に整数が入ってい また、型推論は特定の型を推論することがあります。次のように書いたとします。 -```tut +```scala var obj = null ``` これ以上進められず、再割り当てができません。 -```tut:fail +```scala mdoc:fail obj = new AnyRef ``` diff --git a/_ja/tour/unified-types.md b/_ja/tour/unified-types.md index 7e5b4841d4..8f9710b62a 100644 --- a/_ja/tour/unified-types.md +++ b/_ja/tour/unified-types.md @@ -35,7 +35,7 @@ null非許容です。 以下にstring、integer、character、boolean、関数が他のオブジェクトと同様に全てオブジェクトであるという例を示します。 -```tut +```scala mdoc val list: List[Any] = List( "a string", 732, // integer @@ -67,7 +67,7 @@ true 例えば、 -```tut +```scala mdoc val x: Long = 987654321 val y: Float = x // 9.8765434E8 (この場合精度が落ちることに注意してください) diff --git a/_ja/tour/upper-type-bounds.md b/_ja/tour/upper-type-bounds.md index ac6b1f2440..7d8ac4df9a 100644 --- a/_ja/tour/upper-type-bounds.md +++ b/_ja/tour/upper-type-bounds.md @@ -19,7 +19,7 @@ _上限型境界_ `T <: A` は型変数`T`が型`A`のサブタイプである こちらはクラス`PetContainer`の型パラメータの上限型境界を実演する例です。 -```tut +```scala mdoc abstract class Animal { def name: String } @@ -46,7 +46,7 @@ val dogContainer = new PetContainer[Dog](new Dog) val catContainer = new PetContainer[Cat](new Cat) ``` -```tut:fail +```scala mdoc:fail // これはコンパイルされません val lionContainer = new PetContainer[Lion](new Lion) ``` diff --git a/_ja/tour/variances.md b/_ja/tour/variances.md index 6ec894f79b..c7eb10304e 100644 --- a/_ja/tour/variances.md +++ b/_ja/tour/variances.md @@ -20,7 +20,7 @@ Scalaは[ジェネリッククラス](generic-classes.html)の型パラメータ もし変位指定が無ければ、クラスを抽象化して再利用しにくくなるでしょう。 -```tut +```scala mdoc class Foo[+A] // 共変クラス class Bar[-A] // 反変クラス class Baz[A] // 非変クラス @@ -34,7 +34,7 @@ class Baz[A] // 非変クラス このシンプルなクラス構成を考えてみましょう。 -```tut +```scala mdoc abstract class Animal { def name: String } @@ -49,7 +49,7 @@ Scala標準ライブラリにはイミュータブルなジェネリッククラ 以下の例では、メソッド`printAnimalNames`は引数に動物のリストを受け取り、新しい行にそれらの名前をプリントします。 もし`List[A]`が共変でなければ、最後の2つのメソッド呼び出しはコンパイルされず、`printAnimalNames`メソッドの使い勝手はひどく制限されます。 -```tut +```scala mdoc object CovarianceTest extends App { def printAnimalNames(animals: List[Animal]): Unit = { animals.foreach { animal => @@ -79,7 +79,7 @@ object CovarianceTest extends App { 先に定義された`Cat`、`Dog`、`Animal`クラスを以下の例で検討してみます。 -```tut +```scala mdoc abstract class Printer[-A] { def print(value: A): Unit } @@ -87,7 +87,7 @@ abstract class Printer[-A] { `Printer[A]`はある型`A`をどのようにプリントするかを知っている簡単なクラスです。 特定の型でいくつかのサブクラスを定義してみましょう。 -```tut +```scala mdoc class AnimalPrinter extends Printer[Animal] { def print(animal: Animal): Unit = println("The animal's name is: " + animal.name) @@ -104,7 +104,7 @@ class CatPrinter extends Printer[Cat] { 逆の関係性は適用されません、それは`Printer[Cat]`がコンソールに任意の`Animal`をプリントする方法を知らないからです。 したがって、私達は必要であれば`Printer[Animal]`を`Printer[Cat]`代わりに使うことができます。これは`Printer[A]`が反変であるからこそ可能なのです。 -```tut +```scala mdoc object ContravarianceTest extends App { val myCat: Cat = Cat("Boots") @@ -133,7 +133,7 @@ Scalaのジェネリッククラスは標準では非変です。 これは共変でも反変でもないことを意味します。 以下の例の状況では、`Container`クラスは非変です。`Container[Cat]`は`Container[Animal]`_ではなく_、逆もまた同様です。 -```tut +```scala mdoc class Container[A](value: A) { private var _value: A = value def getValue: A = _value @@ -164,7 +164,7 @@ val cat: Cat = catContainer.getValue // おっと、犬を猫に割り当てて 先ほど利用された`Cat`, `Dog`, `Animal`の継承ツリーに、以下のものを加えましょう: -```tut +```scala mdoc abstract class SmallAnimal extends Animal case class Mouse(name: String) extends SmallAnimal ``` diff --git a/_ko/tour/basics.md b/_ko/tour/basics.md index d52f7f85c9..21c8b94cdf 100644 --- a/_ko/tour/basics.md +++ b/_ko/tour/basics.md @@ -25,17 +25,17 @@ ScalaFiddle를 사용하면 브라우저에서 스칼라를 실행해 볼 수 이 페이지의 많은 예제 코드가 ScalaFiddle와 통합되어 있어 간단히 실행 버튼만 눌러 직접 실험해 볼 수 있다. ## 표현식 - + 표현식은 연산 가능한 명령문이다. -``` +```scala mdoc 1 + 1 ``` `println` 표현식을 사용해 결과를 출력할 수 있다. {% scalafiddle %} -```tut +```scala mdoc println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! @@ -47,20 +47,20 @@ println("Hello," + " world!") // Hello, world! `val` 키워드로 표현식의 결과에 이름을 붙인다. -```tut +```scala mdoc val x = 1 + 1 println(x) // 2 ``` `x` 같이 이름이 붙여진 결과를 값이라고 부른다. 참조된 값은 재연산하지 않으며 값을 재할당할 수 없다. -```tut:fail +```scala mdoc:fail x = 3 // This does not compile. ``` 값의 타입을 추론할 수 있지만 명시적으로 타입을 지정할 수도 있다. -```tut +```scala mdoc:nest val x: Int = 1 + 1 ``` @@ -70,7 +70,7 @@ val x: Int = 1 + 1 변수는 재할당이 가능한 것 이외에는 값과 같다. `var` 키워드로 변수를 정의한다. -```tut +```scala mdoc:nest var x = 1 + 1 x = 3 // This compiles because "x" is declared with the "var" keyword. println(x * x) // 9 @@ -78,7 +78,7 @@ println(x * x) // 9 값처럼 명시적으로 타입을 지정할 수도 있다. -```tut +```scala mdoc:nest var x: Int = 1 + 1 ``` @@ -89,7 +89,7 @@ var x: Int = 1 + 1 블록 안 마지막 표현식의 결과는 블록 전체의 결과이기도 하다. -```tut +```scala mdoc println({ val x = 1 + 1 x + 1 @@ -102,7 +102,7 @@ println({ 주어진 정수에 1을 더하는 익명 함수(이름이 없는 함수)를 정의할 수 있다. -```tut +```scala mdoc (x: Int) => x + 1 ``` @@ -111,7 +111,7 @@ println({ 함수에 이름을 지정할 수 있다. {% scalafiddle %} -```tut +```scala mdoc val addOne = (x: Int) => x + 1 println(addOne(1)) // 2 ``` @@ -120,7 +120,7 @@ println(addOne(1)) // 2 함수는 여러 매개변수를 가질 수 있다. {% scalafiddle %} -```tut +```scala mdoc val add = (x: Int, y: Int) => x + y println(add(1, 2)) // 3 ``` @@ -128,7 +128,7 @@ println(add(1, 2)) // 3 또는 매개변수를 가지지 않을 수도 있다. -```tut +```scala mdoc val getTheAnswer = () => 42 println(getTheAnswer()) // 42 ``` @@ -140,7 +140,7 @@ println(getTheAnswer()) // 42 `def` 키워드로 메소드를 정의하고 이름, 매개변수 목록, 반환 타입 그리고 본문이 뒤따른다. {% scalafiddle %} -```tut +```scala mdoc:nest def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3 ``` @@ -151,7 +151,7 @@ println(add(1, 2)) // 3 메소드는 여러 매개변수 목록을 가질 수 있다. {% scalafiddle %} -```tut +```scala mdoc def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9 ``` @@ -159,7 +159,7 @@ println(addThenMultiply(1, 2)(3)) // 9 또는 매개변수 목록을 가지지 않을 수도 있다. -```tut +```scala mdoc def name: String = System.getProperty("user.name") println("Hello, " + name + "!") ``` @@ -169,7 +169,7 @@ println("Hello, " + name + "!") 메소드는 여러 줄의 표현식을 가질 수 있다. {% scalafiddle %} -```tut +```scala mdoc def getSquareString(input: Double): String = { val square = input * input square.toString @@ -184,7 +184,7 @@ println(getSquareString(2.5)) // 6.25 `class` 키워드로 클래스를 정의하고 이름과 생성자 매개변수가 뒤따른다. -```tut +```scala mdoc class Greeter(prefix: String, suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) @@ -195,7 +195,7 @@ class Greeter(prefix: String, suffix: String) { `new` 키워드로 클래스의 인스턴스를 만든다. -```tut +```scala mdoc val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` @@ -206,13 +206,13 @@ greeter.greet("Scala developer") // Hello, Scala developer! 스칼라는 케이스 클래스라고 불리는 특별한 타입의 클래스를 가지고 있다. 기본적으로, 케이스 클래스는 변하지 않으며 값으로 비교한다. `case class` 키워드로 케이스 클래스를 정의한다. -```tut +```scala mdoc case class Point(x: Int, y: Int) ``` `new` 키워드 없이 케이스 클래스를 인스턴스화 할 수 있다. -```tut +```scala mdoc val point = Point(1, 2) val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2) @@ -220,7 +220,7 @@ val yetAnotherPoint = Point(2, 2) 그리고 값으로 비교한다. -```tut +```scala mdoc if (point == anotherPoint) { println(point + " and " + anotherPoint + " are the same.") } else { @@ -242,7 +242,7 @@ if (point == yetAnotherPoint) { `object` 키워드로 객체를 정의한다. -```tut +```scala mdoc object IdFactory { private var counter = 0 def create(): Int = { @@ -254,7 +254,7 @@ object IdFactory { 객체 이름을 참조하여 객체에 접근할 수 있다. -```tut +```scala mdoc val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() @@ -269,7 +269,7 @@ println(newerId) // 2 `trait` 키워드로 트레이트를 정의한다. -```tut +```scala mdoc:nest trait Greeter { def greet(name: String): Unit } @@ -278,7 +278,7 @@ trait Greeter { 또한 트레이트는 기본 구현도 가질 수 있다. {% scalafiddle %} -```tut +```scala mdoc:reset trait Greeter { def greet(name: String): Unit = println("Hello, " + name + "!") @@ -287,7 +287,7 @@ trait Greeter { `extends` 키워드로 트레이트를 상속할 수 있고 `override` 키워드로 구현을 오버라이드할 수 있다. -```tut +```scala mdoc class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { @@ -314,7 +314,7 @@ customGreeter.greet("Scala developer") // How are you, Scala developer? `object` 키워드를 사용하여 메인 메소드를 정의할 수 있다. -```tut +```scala mdoc object Main { def main(args: Array[String]): Unit = println("Hello, Scala developer!") diff --git a/_ko/tour/case-classes.md b/_ko/tour/case-classes.md index 1dcfe852be..78cf439c26 100644 --- a/_ko/tour/case-classes.md +++ b/_ko/tour/case-classes.md @@ -119,4 +119,4 @@ previous-page: multiple-parameter-lists * 값을 통한 비교는 여러분이 인스턴스들을 원시 값들인 것처럼 비교할수 있게 만들어 준다 - 클래스의 인스턴스들이 값 또는 참조를 통해 비교되는지와 같은 불확실성을 제거 * 패턴매칭은 로직의 분기를 심플하게 만들어주며, 결국 적은 버그와 가독성 높은 코드로 이어진다. -고광현 옮김 \ No newline at end of file +고광현 옮김 diff --git a/_ko/tour/classes.md b/_ko/tour/classes.md index 171079ebb3..a3635881a0 100644 --- a/_ko/tour/classes.md +++ b/_ko/tour/classes.md @@ -16,14 +16,14 @@ prerequisite-knowledge: no-return-keyword, type-declaration-syntax, string-inter # 클래스 정의 가장 단순한 클래스 정의는 예약어 `class`와 식별자만 있는 것입니다. 클래스명은 대문자로 시작하는 것이 관례입니다. -```tut +```scala mdoc class User val user1 = new User ``` 예약어 `new`는 클래스의 인스턴스를 만들기위해 사용합니다. `User` 클래스는 생성자를 정의하지 않았기 때문에 인자가 없는 기본 생성자를 갖습니다. 생성자와 클래스 몸체를 정의하고자 한다면, 다음의 클래스 정의 예제를 참고하십시오: -```tut +```scala mdoc class Point(var x: Int, var y: Int) { def move(dx: Int, dy: Int): Unit = { @@ -46,7 +46,7 @@ println(point1) // prints (2, 3) 생성자는 다음과 같은 기본 값을 제공하여 선택적 매개변수를 가질 수 있습니다: -```tut +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val origin = new Point // x and y are both set to 0 @@ -56,7 +56,7 @@ println(point1.x) // prints 1 ``` 이 버전의 `Point` 클래스에서 `x`와 `y` 인자는 기본 값 `0`을 가지므로 인자를 꼭 전달하지 않아도 됩니다. 생성자는 인자를 왼쪽부터 읽으므로 `y` 값만 전달하고 싶다면 매개변수의 이름을 지정해야 합니다. -``` +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val point2 = new Point(y=2) println(point2.y) // prints 2 @@ -66,7 +66,7 @@ println(point2.y) // prints 2 # Private 멤버와 Getter/Setter 문법 멤버는 기본적으로 public으로 지정됩니다. `private` 접근 지시자를 사용함으로써 클래스 외부로부터 멤버를 숨길 수 있습니다. -```tut +```scala mdoc:nest class Point { private var _x = 0 private var _y = 0 @@ -89,17 +89,17 @@ val point1 = new Point point1.x = 99 point1.y = 101 // 경고가 출력됩니다 ``` -이 버전의 `Point` 클래스에서는 데이터가 private 변수 `_x`와 `_y`에 저장됩니다. 이 private 데이터에 접근하기 위한 메서드 `def x`와 `def y`가 있고, `_x`와 `_y` 값을 검증하고 설정하기위한 `def x_=`와 `def y_=`가 있습니다. setter 메서드를 위한 특별한 문법에 주목하십시오: getter 메서드 식별자에 `_=`를 덧붙이고 매개변수가 뒤따르는 형식입니다. +이 버전의 `Point` 클래스에서는 데이터가 private 변수 `_x`와 `_y`에 저장됩니다. 이 private 데이터에 접근하기 위한 메서드 `def x`와 `def y`가 있고, `_x`와 `_y` 값을 검증하고 설정하기위한 `def x_=`와 `def y_=`가 있습니다. setter 메서드를 위한 특별한 문법에 주목하십시오: getter 메서드 식별자에 `_=`를 덧붙이고 매개변수가 뒤따르는 형식입니다. 기본 생성자에서 `val`와 `var`로 지정된 매개변수는 public 입니다. `val`은 불변을 의미하기 때문에 다음의 예처럼 값을 변경할 수 없습니다. -``` +```scala mdoc:fail class Point(val x: Int, val y: Int) val point = new Point(1, 2) point.x = 3 // <-- 컴파일되지 않습니다 ``` `val` 또는 `var`로 지정되지 않은 매개변수는 private 값이므로 클래스 내에서만 참조가능합니다. -``` +```scala mdoc:fail class Point(x: Int, y: Int) val point = new Point(1, 2) point.x // <-- 컴파일되지 않습니다 diff --git a/_ko/tour/implicit-conversions.md b/_ko/tour/implicit-conversions.md index 3b620ab090..41aa47856e 100644 --- a/_ko/tour/implicit-conversions.md +++ b/_ko/tour/implicit-conversions.md @@ -40,7 +40,7 @@ previous-page: implicit-parameters 예를 들면, `java.lang.Integer`를 기대하는 자바 메서드를 호출할 때, `scala.Int`를 대신 넘겨도 된다. 그 이유는 Predef가 아래 암시적 변환을 포함하기 때문이다. -```tut +```scala mdoc import scala.language.implicitConversions implicit def int2Integer(x: Int) = diff --git a/_ko/tour/inner-classes.md b/_ko/tour/inner-classes.md index 7588145c39..173449ef43 100644 --- a/_ko/tour/inner-classes.md +++ b/_ko/tour/inner-classes.md @@ -85,4 +85,4 @@ previous-page: lower-type-bounds > 이 프로그램에선 하나의 노드를 서로 다른 두 그래프에 추가할 수 없음에 주의하자. 이 제약도 함께 제거하기 위해선 변수 nodes의 타입을 `Graph#Node`로 바꿔야 한다. -윤창석, 이한욱 옮김 \ No newline at end of file +윤창석, 이한욱 옮김 diff --git a/_ko/tour/lower-type-bounds.md b/_ko/tour/lower-type-bounds.md index b5a99e2f19..718983a0a4 100644 --- a/_ko/tour/lower-type-bounds.md +++ b/_ko/tour/lower-type-bounds.md @@ -47,4 +47,4 @@ _주의:_ 새로운 `prepend` 메소드에선 타입의 제약이 조금 줄어 val anyList: ListNode[Any] = strList.prepend(12345) } -윤창석, 이한욱 옮김 \ No newline at end of file +윤창석, 이한욱 옮김 diff --git a/_ko/tour/multiple-parameter-lists.md b/_ko/tour/multiple-parameter-lists.md index ea0ed2fa73..c8cf38cfdc 100644 --- a/_ko/tour/multiple-parameter-lists.md +++ b/_ko/tour/multiple-parameter-lists.md @@ -35,4 +35,4 @@ _주의: `modN` 메소드는 두 번의 `filter` 호출에서 부분적으로 List(2,4,6,8) List(3,6) -윤창석, 이한욱 옮김 \ No newline at end of file +윤창석, 이한욱 옮김 diff --git a/_ko/tour/named-arguments.md b/_ko/tour/named-arguments.md index 7386c3c563..53fa5182a9 100644 --- a/_ko/tour/named-arguments.md +++ b/_ko/tour/named-arguments.md @@ -33,4 +33,4 @@ previous-page: default-parameter-values 여러분이 원하는 순서대로 파라미터를 위치시킬 수 있기 때문에 파라미터 목록 중에서 가장 중요한 파라미터부터 기본 값을 사용할 수 있다. -윤창석, 이한욱 옮김 \ No newline at end of file +윤창석, 이한욱 옮김 diff --git a/_ko/tour/nested-functions.md b/_ko/tour/nested-functions.md index ba90ee4a60..a26a6a64a3 100644 --- a/_ko/tour/nested-functions.md +++ b/_ko/tour/nested-functions.md @@ -29,4 +29,4 @@ _주의: 중첩 함수 `process`는 `filter`의 파라미터 값으로써 외부 List(1,2,3,4) -윤창석, 이한욱 옮김 \ No newline at end of file +윤창석, 이한욱 옮김 diff --git a/_ko/tour/packages-and-imports.md b/_ko/tour/packages-and-imports.md index c978597d53..4a40cf7bf5 100644 --- a/_ko/tour/packages-and-imports.md +++ b/_ko/tour/packages-and-imports.md @@ -78,7 +78,7 @@ import users.{UserPreferences => UPrefs} // 편의를 위해 이름을 바꾸 스칼라가 자바와 한가지 다른 점은 어디서든 임포트를 할 수 있다는 것이다. -```tut +```scala mdoc def sqrtplus1(x: Int) = { import scala.math.sqrt sqrt(x) + 1.0 diff --git a/_ko/tour/pattern-matching.md b/_ko/tour/pattern-matching.md index e860caed3a..3ee2efd1d0 100644 --- a/_ko/tour/pattern-matching.md +++ b/_ko/tour/pattern-matching.md @@ -40,4 +40,4 @@ previous-page: case-classes 스칼라의 패턴 매칭 명령문은 [케이스 클래스](case-classes.html)를 통해 표현되는 대수 타입과 매칭할 때 가장 유용하다. 또한 스칼라는 [추출자 오브젝트](extractor-objects.html)의 `unapply` 메소드를 사용해, 독립적인 케이스 클래스로 패턴을 정의할 수 있도록 해준다. -윤창석, 이한욱 옮김 \ No newline at end of file +윤창석, 이한욱 옮김 diff --git a/_ko/tour/regular-expression-patterns.md b/_ko/tour/regular-expression-patterns.md index 12ffd6caae..4f71d15e49 100644 --- a/_ko/tour/regular-expression-patterns.md +++ b/_ko/tour/regular-expression-patterns.md @@ -40,4 +40,4 @@ previous-page: singleton-objects 정규 표현식 패턴이 XML 처리에 예상에 비해 그다지 유용하지 않다는 것이 우리의 의견이다. 실제 상황에서 XML를 처리해야하는 애플리케이션이라면 XPath가 더 나은 선택으로 보인다. 우리의 변환이나 정규 표현식 패턴에 드물지만 제거하기 어려운 난해한 버그가 있다는 점을 발견했을 때, 우리는 이 기회에 언어를 좀 더 단순하게 만들기로 결정했다. -윤창석, 이한욱 옮김 \ No newline at end of file +윤창석, 이한욱 옮김 diff --git a/_ko/tour/self-types.md b/_ko/tour/self-types.md index bd99c389c7..56ca99a2e6 100644 --- a/_ko/tour/self-types.md +++ b/_ko/tour/self-types.md @@ -98,4 +98,4 @@ previous-page: compound-types n1.connectWith(n3) } -윤창석, 이한욱 옮김 \ No newline at end of file +윤창석, 이한욱 옮김 diff --git a/_ko/tour/singleton-objects.md b/_ko/tour/singleton-objects.md index 64f14c43f6..bc5ffaa359 100644 --- a/_ko/tour/singleton-objects.md +++ b/_ko/tour/singleton-objects.md @@ -34,7 +34,7 @@ object Blah { 하나의 클래스와 그 동반자 객체는 어떤 경우라도, 아래와 같이 *같은* 소스파일에 정의되어야 한다. -```tut +```scala mdoc class IntPair(val x: Int, val y: Int) object IntPair { diff --git a/_ko/tour/traits.md b/_ko/tour/traits.md index 655a5557b3..1dd3fb34d9 100644 --- a/_ko/tour/traits.md +++ b/_ko/tour/traits.md @@ -16,12 +16,12 @@ prerequisite-knowledge: expressions, classes, generics, objects, companion-objec # 트레잇 정의 가장 단순한 트레잇 정의는 예약어 `trait`과 식별자만 있는 것입니다: -```tut +```scala mdoc trait HairColor ``` 트레잇은 제네릭 타입과 추상 메서드로 특히 유용합니다. -```tut +```scala mdoc trait Iterator[A] { def hasNext: Boolean def next(): A @@ -32,7 +32,7 @@ trait Iterator[A] { ## 트레잇 사용하기 `extends` 예약어를 사용하여 트레잇을 확장하십시오. 그런 다음 `override` 예약어를 사용하여 트레잇의 추상 멤버를 구현하십시오: -```tut +```scala mdoc:nest trait Iterator[A] { def hasNext: Boolean def next(): A @@ -59,7 +59,7 @@ iterator.next() // returns 1 ## 서브타이핑 특정 트레잇이 필요한 곳에 그 트레잇의 서브타입을 대신 사용할 수 있습니다. -```tut +```scala mdoc import scala.collection.mutable.ArrayBuffer trait Pet { diff --git a/_ko/tour/tuples.md b/_ko/tour/tuples.md index e699f7f78f..e4b7ff32c0 100644 --- a/_ko/tour/tuples.md +++ b/_ko/tour/tuples.md @@ -18,7 +18,7 @@ topics: tuples 두개의 엘리먼트를 갖는 튜플은 다음과 같이 생성할 수 있다: -```tut +```scala mdoc val ingredient = ("Sugar" , 25) ``` @@ -33,7 +33,7 @@ val ingredient = ("Sugar" , 25) 튜플의 엘리먼트에 접근하기 위한 한가지 방법은 위치로 접근하는 것이다. 각 요소들은 `_1`, `_2`, ... 와 같은 이름을 갖는다. -```tut +```scala mdoc println(ingredient._1) // Sugar println(ingredient._2) // 25 ``` @@ -42,7 +42,7 @@ println(ingredient._2) // 25 하나의 튜플은 패턴 매칭을 사용하여 분리할 수 있다: -```tut +```scala mdoc val (name, quantity) = ingredient println(name) // Sugar println(quantity) // 25 @@ -52,7 +52,7 @@ println(quantity) // 25 여기 튜플을 패턴 매칭한 또 다른 예제가 있다: -```tut +```scala mdoc val planets = List(("Mercury", 57.9), ("Venus", 108.2), ("Earth", 149.6), ("Mars", 227.9), ("Jupiter", 778.3)) @@ -65,7 +65,7 @@ planets.foreach{ 또는 `for` comprehension에서: -```tut +```scala mdoc val numPairs = List((2, 5), (3, -7), (20, 56)) for ((a, b) <- numPairs) { println(a * b) diff --git a/_ko/tour/type-inference.md b/_ko/tour/type-inference.md index c3daf79e72..189b334593 100644 --- a/_ko/tour/type-inference.md +++ b/_ko/tour/type-inference.md @@ -51,4 +51,4 @@ previous-page: polymorphic-methods 이 프로그램은 변수 `obj`의 타입 추론이 `Null`이기 때문에 컴파일되지 않는다. 해당 타입의 유일한 값이 `null`이기 때문에 이 변수는 다른 값을 나타낼 수 없다. -윤창석, 이한욱 옮김 \ No newline at end of file +윤창석, 이한욱 옮김 diff --git a/_ko/tour/unified-types.md b/_ko/tour/unified-types.md index 3b13b95978..989ef50d6b 100644 --- a/_ko/tour/unified-types.md +++ b/_ko/tour/unified-types.md @@ -27,7 +27,7 @@ prerequisite-knowledge: classes, basics 다음 소스는 문자열 값, 정수 값, 문자 값, boolean 값과 함수 역시 모두 객체로 취급됨을 보여주는 샘플입니다: -```tut +```scala mdoc val list: List[Any] = List( "a string", 732, // 정수 값 @@ -57,7 +57,7 @@ true 예제: -```tut +```scala mdoc val x: Long = 987654321 val y: Float = x // 9.8765434E8 (이 경우 일부 자리수가 소실되었음을 주의) diff --git a/_ko/tour/variances.md b/_ko/tour/variances.md index 7cc2b404ac..b8049a6a5c 100644 --- a/_ko/tour/variances.md +++ b/_ko/tour/variances.md @@ -14,7 +14,7 @@ previous-page: generic-classes [제네릭 클래스](generic-classes.html)에 관한 페이지에선 변경 가능한 스택의 예제를 살펴보면서, 클래스 `Stack[T]`에서 정의한 타입은 타입 파라미터의 서브타입이 불변자여야 함을 설명했었다. 이는 추상화된 클래스의 재사용을 제한할 수 있다. 지금부턴 이런 제약이 없는 함수형(즉, 변경이 불가능한) 스택의 구현을 알아본다. 이 구현은 [다형성 메소드](polymorphic-methods.html), [하위 타입 경계](lower-type-bounds.html), 순가변 타입 파라미터 어노테이션 등의 중요 개념을 조합한 좀 더 어려운 예제임을 알아두자. 또한 [내부 클래스](inner-classes.html)를 사용해 명시적인 연결 없이도 스택의 항목을 서로 묶을 수 있도록 만들었다. -```tut +```scala mdoc class Stack[+T] { def push[S >: T](elem: S): Stack[S] = new Stack[S] { override def top: S = elem diff --git a/_overviews/contributors/index.md b/_overviews/contributors/index.md index 4a685c7a70..0c6ed3482a 100644 --- a/_overviews/contributors/index.md +++ b/_overviews/contributors/index.md @@ -496,13 +496,13 @@ For instance, given the following `src/documentation/getting-started.md` file: First, start with the following import: -```tut +```scala import ch.epfl.scala.Example ``` Then, do nothing with something: -```tut +```scala Example.doNothing(42) ``` {% endhighlight %} diff --git a/_overviews/core/custom-collection-operations.md b/_overviews/core/custom-collection-operations.md index 87b2f863ae..25f792fd7a 100644 --- a/_overviews/core/custom-collection-operations.md +++ b/_overviews/core/custom-collection-operations.md @@ -118,7 +118,7 @@ res2: Set[Int] = HashSet(-1775377531, -1376640531, -1009522404, 526943297, 14318 A very basic definition of `Gen[A]` could be the following: -```tut +```scala mdoc trait Gen[A] { /** Get a generated value of type `A` */ def get: A @@ -127,7 +127,7 @@ trait Gen[A] { And the following instances can be defined: -```tut +```scala mdoc import scala.util.Random object Gen { @@ -330,4 +330,4 @@ be `List[Int]`. - To also support `String`, `Array` and `View`, use `IsIterable`, - To produce a collection given its type, use a `Factory`, - To produce a collection based on the type of a source collection and the type of elements of the collection - to produce, use `BuildFrom`. \ No newline at end of file + to produce, use `BuildFrom`. diff --git a/_overviews/scaladoc/contribute.md b/_overviews/scaladoc/contribute.md index c922afa863..c902e99f97 100644 --- a/_overviews/scaladoc/contribute.md +++ b/_overviews/scaladoc/contribute.md @@ -25,4 +25,4 @@ which covers the steps and workflow necessary work on the Scaladoc tool. As of Scala 2.13, the Scaladoc tool is maintained but not actively developed. Major development of Scaladoc will progress as a part of Dotty for Scala 3 in the -[Dottydoc](https://dotty.epfl.ch/docs/usage/dottydoc.html) tool. \ No newline at end of file +[Dottydoc](https://dotty.epfl.ch/docs/usage/dottydoc.html) tool. diff --git a/_pl/tour/abstract-type-members.md b/_pl/tour/abstract-type-members.md index b8f6b7770f..d47ebe86af 100644 --- a/_pl/tour/abstract-type-members.md +++ b/_pl/tour/abstract-type-members.md @@ -13,7 +13,7 @@ W Scali klasy są parametryzowane wartościami (parametry konstruktora) oraz typ Poniższy przykład definiuje wartość określaną przez abstrakcyjny typ będący elementem [cechy](traits.html) `Buffer`: -```tut +```scala mdoc trait Buffer { type T val element: T @@ -24,7 +24,7 @@ trait Buffer { W poniższym programie definiujemy klasę `SeqBuffer`, która ogranicza możliwe typy `T` do pochodnych sekwencji `Seq[U]` dla nowego typu `U`: -```tut +```scala mdoc:nest abstract class SeqBuffer extends Buffer { type U type T <: Seq[U] @@ -34,7 +34,7 @@ abstract class SeqBuffer extends Buffer { Cechy oraz [klasy](classes.html) z abstrakcyjnymi typami są często używane w połączeniu z anonimowymi klasami. Aby to zilustrować, wykorzystamy program, w którym utworzymy bufor sekwencji ograniczony do listy liczb całkowitych: -```tut +```scala mdoc:nest abstract class IntSeqBuffer extends SeqBuffer { type U = Int } @@ -55,7 +55,7 @@ Typ zwracany przez metodę `newIntSeqBuf` nawiązuje do specjalizacji cechy `Buf Warto zwrócić uwagę, że często jest możliwa zamiana abstrakcyjnych typów w parametry typów klas i odwrotnie. Poniższy przykład stosuje wyłącznie parametry typów: -```tut +```scala mdoc:nest abstract class Buffer[+T] { val element: T } diff --git a/_pl/tour/automatic-closures.md b/_pl/tour/automatic-closures.md index d0aaca2161..5f28a2568a 100644 --- a/_pl/tour/automatic-closures.md +++ b/_pl/tour/automatic-closures.md @@ -13,7 +13,7 @@ Scala pozwala na przekazywanie funkcji bezparametrycznych jako argumenty dla met Poniższy kod demonstruje działanie tego mechanizmu: -```tut +```scala mdoc object TargetTest1 extends App { def whileLoop(cond: => Boolean)(body: => Unit): Unit = if (cond) { @@ -34,7 +34,7 @@ Możemy połączyć ze sobą wykorzystanie [operatorów infiksowych/postfiksowyc Oto implementacja pętli w stylu wykonaj-dopóki: -```tut +```scala mdoc object TargetTest2 extends App { def loop(body: => Unit): LoopUnlessCond = new LoopUnlessCond(body) diff --git a/_pl/tour/basics.md b/_pl/tour/basics.md index 932bb890c7..903ecdcfe7 100644 --- a/_pl/tour/basics.md +++ b/_pl/tour/basics.md @@ -28,14 +28,14 @@ dzięki czemu można je wypróbować wciskając po prostu przycisk "Run". Wyrażenia są rezultatem ewaluacji fragmentów kodu. -``` +```scala mdoc 1 + 1 ``` Wyniki wyrażeń można wyświetlić za pomocą funkcji `println`. {% scalafiddle %} -```tut +```scala mdoc println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! @@ -47,7 +47,7 @@ println("Hello," + " world!") // Hello, world! Rezultaty wyrażeń mogą zostać nazwane za pomocą słowa kluczowego `val`. -```tut +```scala mdoc val x = 1 + 1 println(x) // 2 ``` @@ -57,13 +57,13 @@ Odniesienie się do wartości nie powoduje jej ponownego obliczenia. Wartości nie można przypisać ponownie. -```tut:fail +```scala mdoc:fail x = 3 // Nie kompiluje się. ``` Typy wartości mogą być wywnioskowane przez kompilator, ale można również wyraźnie określić type: -```tut +```scala mdoc:nest val x: Int = 1 + 1 ``` @@ -75,7 +75,7 @@ Zmienne są podobne do wartości, ale z tym wyjątkiem, że można je ponownie p Zmienną można zdefiniować używając słowa kluczowego `var`. {% scalafiddle %} -```tut +```scala mdoc:nest var x = 1 + 1 x = 3 // Kompiluje się, ponieważ "x" jest zdefiniowane z użyciem "var". println(x * x) // 9 @@ -84,7 +84,7 @@ println(x * x) // 9 Tak jak przy wartościach, można wyraźnie zdefiniować żądany typ: -```tut +```scala mdoc:nest var x: Int = 1 + 1 ``` @@ -95,7 +95,7 @@ Taką konstrukcję nazywamy blokiem. Wynikiem całego bloku kodu jest wynik ostatniego wyrażenia w tym bloku. {% scalafiddle %} -```tut +```scala mdoc println({ val x = 1 + 1 x + 1 @@ -109,7 +109,7 @@ Funkcje to wyrażenia, które przyjmują pewne parametry. Poniżej zdefiniowana jest funkcja anonimowa (nieposiadająca nazwy), która zwraca liczbę całkowitą przekazaną jako parametr, zwiększoną o 1. -```tut +```scala mdoc (x: Int) => x + 1 ``` @@ -119,7 +119,7 @@ Po prawej stronie - wyrażenie wykorzystujące te parametry. Funkcje można również nazywać. {% scalafiddle %} -```tut +```scala mdoc val addOne = (x: Int) => x + 1 println(addOne(1)) // 2 ``` @@ -128,7 +128,7 @@ println(addOne(1)) // 2 Funkcje mogą przyjmować wiele parametrów. {% scalafiddle %} -```tut +```scala mdoc val add = (x: Int, y: Int) => x + y println(add(1, 2)) // 3 ``` @@ -137,7 +137,7 @@ println(add(1, 2)) // 3 Mogą też wcale nie mieć parametrow. {% scalafiddle %} -```tut +```scala mdoc val getTheAnswer = () => 42 println(getTheAnswer()) // 42 ``` @@ -151,7 +151,7 @@ Metody są definiowane z użyciem słowa kluczowego `def`. Po `def` następuje nazwa metody, lista parametrów, zwracany typ i ciało metody. {% scalafiddle %} -```tut +```scala mdoc:nest def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3 ``` @@ -162,7 +162,7 @@ Zauważ, że zwracany typ jest zadeklarowany _po_ liście parametrów i dwukropk Metody mogą mieć wiele list parametrów. {% scalafiddle %} -```tut +```scala mdoc def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9 ``` @@ -171,7 +171,7 @@ println(addThenMultiply(1, 2)(3)) // 9 Mogą również wcale ich nie posiadać. {% scalafiddle %} -```tut +```scala mdoc def name: String = System.getProperty("user.name") println("Hello, " + name + "!") ``` @@ -182,7 +182,7 @@ Od funkcji odróżnia je jeszcze kilka innych rzeczy, ale na razie możesz o nic Metody mogą zawierać również wyrażenia wielowierszowe. {% scalafiddle %} -```tut +```scala mdoc def getSquareString(input: Double): String = { val square = input * input square.toString @@ -199,7 +199,7 @@ Scala posiada słowo kluczowe `return`, ale jest ono wykorzystywane bardzo rzadk Klasy są definiowane za pomocą słowa kluczowego `class`, po którym następuje nazwa klasy i parametry konstruktora. {% scalafiddle %} -```tut +```scala mdoc class Greeter(prefix: String, suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) @@ -212,7 +212,7 @@ Różnica polega na tym, że w Scali każde wyrażenie musi zwracać jakąś war Nowe instancje klasy tworzy się za pomocą słowa kluczowego `new`. -```tut +```scala mdoc val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` @@ -227,13 +227,13 @@ Klasy przypadku są domyślnie niezmienne i porównywane przez wartości. Klasy te można definiować używająć słów kluczowych `case class`. {% scalafiddle %} -```tut +```scala mdoc case class Point(x: Int, y: Int) ``` Do utworzenia nowej instacji klasy przypadku nie jest konieczne używanie słowa kluczowego `new`. -```tut +```scala mdoc val point = Point(1, 2) val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2) @@ -241,7 +241,7 @@ val yetAnotherPoint = Point(2, 2) Są one porównywane przez wartości - _nie_ przez referencje. -```tut +```scala mdoc if (point == anotherPoint) { println(point + " i " + anotherPoint + " są jednakowe.") } else { @@ -267,7 +267,7 @@ Można o nich myśleć jak o instancjach ich własnych klas - singletonach. Objekty definiuje się z użyciem słowa kluczowego `object`. {% scalafiddle %} -```tut +```scala mdoc object IdFactory { private var counter = 0 def create(): Int = { @@ -279,7 +279,7 @@ object IdFactory { Aby uzyskać dostęp do obiektu używa się jego nazwy. -```tut +```scala mdoc val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() @@ -296,7 +296,7 @@ Wiele cech może być łączonych. Cechę (trait) można zdefiniować używając słowa kluczowego `trait`. -```tut +```scala mdoc:nest trait Greeter { def greet(name: String): Unit } @@ -305,7 +305,7 @@ trait Greeter { Cechy mogą zawierać domyślną implementację. {% scalafiddle %} -```tut +```scala mdoc:reset trait Greeter { def greet(name: String): Unit = println("Hello, " + name + "!") @@ -314,7 +314,7 @@ trait Greeter { Cechy można rozszerzać używając słowa kluczowego `extends` i nadpisać implementację z użyciem `override`. -```tut +```scala mdoc class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { @@ -342,7 +342,7 @@ Maszyna Wirtalna Javy (Java Virtual Machine / JVM) wymaga, aby metoda ta nazywa Z użyciem obiektu można zdefiniować metodę `main` w następujący sposób: -```tut +```scala mdoc object Main { def main(args: Array[String]): Unit = println("Hello, Scala developer!") diff --git a/_pl/tour/by-name-parameters.md b/_pl/tour/by-name-parameters.md index 2bf59f5ef6..21cf9cc758 100644 --- a/_pl/tour/by-name-parameters.md +++ b/_pl/tour/by-name-parameters.md @@ -11,7 +11,7 @@ language: pl _Parametry przekazywane według nazwy_ są ewaluowane za każdym razem gdy są używane. Nie zostaną w ogóle wyewaluowane jeśli nie będą używane. Jest to podobne do zastępowania parametrów w ciele funkcji wyrażeniami podanymi w miejscu jej wywołania. Są przeciwieństwem do _parametrów przekazywanych według wartości_. Aby utworzyć parametr przekazywany według nazwy, po prostu dodaj `=>` przed jego typem. -```tut +```scala mdoc def calculate(input: => Int) = input * 37 ``` @@ -19,7 +19,7 @@ Parametry przekazywane według nazwy mają tę zaletę że nie są ewaluowane je Oto przykład, jak możemy zaimplementować pętlę while: -```tut +```scala mdoc def whileLoop(condition: => Boolean)(body: => Unit): Unit = if (condition) { body diff --git a/_pl/tour/case-classes.md b/_pl/tour/case-classes.md index fcf4bd1f57..cc7346a277 100644 --- a/_pl/tour/case-classes.md +++ b/_pl/tour/case-classes.md @@ -18,7 +18,7 @@ W dalszych rozdziałach przyjrzymy się jak przydają się w [dopasowywaniu wzor Minimalna definicja klasy przypadku wymaga słów kluczowych `case class`, identyfikatora oraz listy parametrów (może być pusta): -```tut +```scala mdoc case class Book(isbn: String) val frankenstein = Book("978-0486282114") @@ -44,7 +44,7 @@ Alternatywnie, w klasach przypadków można też używać `var`, jednak stanowc Klasy przypadków są porównywane według ich struktury, a nie przez referencje: -```tut +```scala mdoc case class Message(sender: String, recipient: String, body: String) val message2 = Message("jorge@catalonia.es", "guillaume@quebec.ca", "Com va?") @@ -59,7 +59,7 @@ Mimo, że `message1` oraz `message2` odnoszą się do innych obiektów, to ich w Możliwe jest stworzenie płytkiej kopii (ang. shallow copy) instancji klasy przypadku używając metody `copy`. Opcjonalnie można zmienić jeszcze wybrane parametry konstruktora. -```tut +```scala mdoc:nest case class Message(sender: String, recipient: String, body: String) val message4 = Message("julien@bretagne.fr", "travis@washington.us", "Me zo o komz gant ma amezeg") val message5 = message4.copy(sender = message4.recipient, recipient = "claire@bourgogne.fr") diff --git a/_pl/tour/classes.md b/_pl/tour/classes.md index 6325c3c2f8..00a4734cbd 100644 --- a/_pl/tour/classes.md +++ b/_pl/tour/classes.md @@ -18,7 +18,7 @@ Typy, obiekty i cechy zostaną omówione w dalszej części przewodnika. Minimalna definicja klasy składa się ze słowa kluczowego `class` oraz jej identyfikatora. Nazwy klas powinny zaczynać się z wielkiej litery. -```tut +```scala mdoc class User val user1 = new User @@ -29,7 +29,7 @@ Ponieważ żaden konstruktor nie został zdefiniowany, klasa `User` posiada kons Zazwyczaj jednak definiujemy konstruktor i ciało klasy. Poniższy przykład przedstawia definicję klasy służącej do reprezentowania punktu. -```tut +```scala mdoc class Point(var x: Int, var y: Int) { def move(dx: Int, dy: Int): Unit = { @@ -57,7 +57,7 @@ Ponieważ `toString` nadpisuje metodę `toString` zdefiniowaną w [`AnyRef`](un Konstruktory mogą zawierać parametry opcjonalne - wystarczy dostarczyć wartość domyślną dla takiego parametru. -```tut +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val origin = new Point // x i y są mają wartość 0 @@ -69,7 +69,7 @@ println(point1.x) // wyświetla 1 W tej wersji klasy `Point`, `x` oraz `y` mają domyślną wartość `0` - dlatego nie jest wymagane przekazanie żadnych parametrów. Jednak z powodu tego, że konstruktor jest ewaluowany od lewej do prawej strony, jeżeli chcesz przekazać parametr tylko do argumentu `y`, musisz określić nazwę tego parametru. -``` +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val point2 = new Point(y = 2) println(point2.y) // wyświetla 2 @@ -82,7 +82,7 @@ Jest to również dobra praktyka, która zwiększa przejrzystość kodu. Domyślnie wszystkie składniki klasy są publiczne. Aby ukryć je przed zewnętrznymi klientami (wszystkim co jest poza daną klasą), należy użyć słowa kluczowego `private`. -```tut +```scala mdoc:nest class Point { private var _x = 0 private var _y = 0 @@ -114,7 +114,7 @@ Zwróć uwagę na specyficzną składnię dla setterów: posiadają one `_=` do Parametry głównego konstruktora oznaczone przez `val` i `var` są publiczne. Ponieważ `val` jest niezmienne, poniższy kod nie jest prawidłowy -``` +```scala mdoc:fail class Point(val x: Int, val y: Int) val point = new Point(1, 2) point.x = 3 // <-- nie kompiluje się @@ -122,7 +122,7 @@ point.x = 3 // <-- nie kompiluje się Parametry konstruktora __nie__ zawierające `val` lub `var` są prywatne - widoczne jedynie we wnętrzu klasy. -``` +```scala mdoc:fail class Point(x: Int, y: Int) val point = new Point(1, 2) point.x // <-- nie kompiluje się diff --git a/_pl/tour/compound-types.md b/_pl/tour/compound-types.md index ffe86317b6..c60b379f7b 100644 --- a/_pl/tour/compound-types.md +++ b/_pl/tour/compound-types.md @@ -13,7 +13,7 @@ Czasami konieczne jest wyrażenie, że dany typ jest podtypem kilku innych typó Załóżmy, że mamy dwie cechy `Cloneable` i `Resetable`: -```tut +```scala mdoc trait Cloneable extends java.lang.Cloneable { override def clone(): Cloneable = { super.clone().asInstanceOf[Cloneable] diff --git a/_pl/tour/default-parameter-values.md b/_pl/tour/default-parameter-values.md index 94883f7cd8..460356deaf 100644 --- a/_pl/tour/default-parameter-values.md +++ b/_pl/tour/default-parameter-values.md @@ -50,7 +50,7 @@ Mimo że powstrzymuje to nas od powtarzania się, to podejście nie jest zbyt wy Scala wprowadza bezpośrednie wsparcie dla domyślnych parametrów: -```tut +```scala mdoc class HashMap[K,V](initialCapacity: Int = 16, loadFactor: Float = 0.75f) { } diff --git a/_pl/tour/extractor-objects.md b/_pl/tour/extractor-objects.md index ee974014f0..17fa3461d7 100644 --- a/_pl/tour/extractor-objects.md +++ b/_pl/tour/extractor-objects.md @@ -11,7 +11,7 @@ previous-page: regular-expression-patterns W Scali wzorce mogą być zdefiniowane niezależnie od klas przypadków. Obiekt posiadający metodę `unapply` może funkcjonować jako tak zwany ekstraktor. Jest to szczególna metoda, która pozwala na odwrócenie zastosowania obiektu dla pewnych danych. Jego celem jest ekstrakcja danych, z których został on utworzony. Dla przykładu, poniższy kod definiuje ekstraktor dla [obiektu](singleton-objects.html) `Twice`: -```tut +```scala mdoc object Twice { def apply(x: Int): Int = x * 2 def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z/2) else None diff --git a/_pl/tour/for-comprehensions.md b/_pl/tour/for-comprehensions.md index 4e70b1627a..6d0c3ab0c9 100644 --- a/_pl/tour/for-comprehensions.md +++ b/_pl/tour/for-comprehensions.md @@ -16,7 +16,7 @@ _For comprehensions_ przedstawione jest w formie `for (enumerators) yield e`, gd Poniżej znajduje się przykład, który przekształca listę osób na listę imion osób, których wiek mieści się w przedziale od 30 do 40 lat. -```tut +```scala mdoc case class Person(name: String, age: Int) val people = List( @@ -37,7 +37,7 @@ Na początku `for` znajduje się generator `person <- people`. Następujące po Poniżej znajduje się bardziej złożony przykład, który używa dwóch generatorów. Jego zadaniem jest sprawdzenie wszystkich par liczb od `0` do `n-1` i wybór tylko tych par, których wartości są sobie równe. -```tut +```scala mdoc def someTuple(n: Int) = for ( i <- 0 until n; @@ -63,7 +63,7 @@ Załóżmy, że mamy dwie wartości `Option[String]` i chcielibyśmy zwrócić o Spójrzmy poniżej: -```tut +```scala mdoc case class Student(name: String, surname: String) val nameOpt: Option[String] = Some("John") @@ -80,7 +80,7 @@ Jeżeli `name` lub `surname` nie byłyby określone, np. przyjmowałyby wartoś Wszystkie powyższe przykłady posiadały wyrażenie `yield` na końcu _comprehensions_, jednak nie jest to obligatoryjne. Gdy `yield` nie zostanie dodanie zwrócony zostanie `Unit`. Takie rozwiązanie może być przydatne gdy chcemy uzyskać jakieś skutki uboczne. Poniższy przykład wypisuje liczby od 0 do 9 bez użycia `yield`. -```tut +```scala mdoc def count(n: Int) = for (i <- 0 until n) println(s"$i ") diff --git a/_pl/tour/generic-classes.md b/_pl/tour/generic-classes.md index 5552d9931f..69599e9b7e 100644 --- a/_pl/tour/generic-classes.md +++ b/_pl/tour/generic-classes.md @@ -13,7 +13,7 @@ Scala posiada wbudowaną obsługą klas parametryzowanych przez typy. Tego typu Poniższy przykład demonstruje zastosowanie parametrów generycznych: -```tut +```scala mdoc class Stack[T] { var elems: List[T] = Nil def push(x: T) { elems = x :: elems } @@ -26,7 +26,7 @@ Klasa `Stack` modeluje zmienny stos zawierający elementy dowolnego typu `T`. Pa Przykłady zastosowania: -```tut +```scala mdoc object GenericsTest extends App { val stack = new Stack[Int] stack.push(1) diff --git a/_pl/tour/higher-order-functions.md b/_pl/tour/higher-order-functions.md index 7180e0a351..2a1a919e04 100644 --- a/_pl/tour/higher-order-functions.md +++ b/_pl/tour/higher-order-functions.md @@ -16,7 +16,7 @@ Terminologia może w tym momencie wydawać się niejasna, pojęcie "funkcja wyż Jednym z najczęściej spotykanych przykładów funkcji wyższego rzędu jest funkcja `map`, która dostępna jest dla kolekcji w Scali. -```tut +```scala mdoc val salaries = Seq(20000, 70000, 40000) val doubleSalary = (x: Int) => x * 2 val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000) @@ -37,7 +37,7 @@ Zauważ, że w powyższym przykładzie `x` nie jest zadeklarowane jako typ `Int` Dzieje się tak, ponieważ kompilator może wywnioskować typ, bazując na typie funkcji oczekiwanej przez `map`. Poniżej jeszcze bardziej idiomatyczny sposób napisania tego kodu: -```tut +```scala mdoc:nest val salaries = Seq(20000, 70000, 40000) val newSalaries = salaries.map(_ * 2) ``` @@ -67,7 +67,7 @@ Jednym z powodów użycia funkcji wyższego rzędu jest zredukowanie nadmiaroweg Powiedzmy, że chcemy stworzyć metody, które potrafią zwiększyć czyjeś wynagrodzenie wg. jakiegoś współczynnika. Bez użycia funkcji wyższego rzędu mogłoby to wyglądać w następujący sposób: -```tut +```scala mdoc object SalaryRaiser { def smallPromotion(salaries: List[Double]): List[Double] = @@ -84,7 +84,7 @@ object SalaryRaiser { Zauważ, że każda z trzech metod różni się jedynie współczynnikiem z jakim zmienia wynagrodzenie. Aby to uprościć, możemy wydzielić powtórzony kod do funkcji wyższego rzędu: -```tut +```scala mdoc:nest object SalaryRaiser { private def promotion(salaries: List[Double], promotionFunction: Double => Double): List[Double] = @@ -108,7 +108,7 @@ Nowa metoda, `promotion`, przyjmuje jako parametr listę wynagrodzeń oraz funkc Istnieją pewne sytuacje, kiedy chcemy wygenerować jakieś funkcje. Oto przykład funkcji zwracającej inną funkcję. -```tut +```scala mdoc def urlBuilder(ssl: Boolean, domainName: String): (String, String) => String = { val schema = if (ssl) "https://" else "http://" (endpoint: String, query: String) => s"$schema$domainName/$endpoint?$query" diff --git a/_pl/tour/implicit-conversions.md b/_pl/tour/implicit-conversions.md index 86d7fa829e..d859139ee8 100644 --- a/_pl/tour/implicit-conversions.md +++ b/_pl/tour/implicit-conversions.md @@ -40,7 +40,7 @@ Domyślnie importowany obiekt `scala.Predef` deklaruje kilka predefiniowanych ty Przykładowo, kiedy wywołujemy metodę Javy, która wymaga typu `java.lang.Integer`, dopuszczalne jest przekazanie typu `scala.Int`. Dzieje się tak ponieważ `Predef` definiuje poniższe konwersje niejawne: -```tut +```scala mdoc import scala.language.implicitConversions implicit def int2Integer(x: Int) = diff --git a/_pl/tour/implicit-parameters.md b/_pl/tour/implicit-parameters.md index ff9aa761b9..2ce27415ea 100644 --- a/_pl/tour/implicit-parameters.md +++ b/_pl/tour/implicit-parameters.md @@ -18,7 +18,7 @@ Argumenty, które mogą być przekazywane jako parametry domniemane, można podz W poniższym przykładzie zdefiniujemy metodę `sum`, która oblicza sumę listy elementów wykorzystując operacje `add` i `unit` obiektu `Monoid`. Należy dodać, że wartości domniemane nie mogą być zdefiniowane globalnie, tylko muszą być elementem pewnego modułu. -```tut +```scala mdoc /** Ten przykład wykorzystuje strukturę z algebry abstrakcyjnej aby zilustrować działanie parametrów domniemanych. Półgrupa jest strukturą algebraiczną na zbiorze A z łączną operacją (czyli taką, która spełnia warunek: add(x, add(y, z)) == add(add(x, y), z)) nazwaną add, która łączy parę obiektów A by zwrócić inny obiekt A. */ abstract class SemiGroup[A] { def add(x: A, y: A): A diff --git a/_pl/tour/inner-classes.md b/_pl/tour/inner-classes.md index 3635d7cccb..2f3fef4ea1 100644 --- a/_pl/tour/inner-classes.md +++ b/_pl/tour/inner-classes.md @@ -11,7 +11,7 @@ previous-page: lower-type-bounds W Scali możliwe jest zdefiniowanie klasy jako element innej klasy. W przeciwieństwie do języków takich jak Java, gdzie tego typu wewnętrzne klasy są elementami ujmujących ich klas, w Scali są one związane z zewnętrznym obiektem. Aby zademonstrować tę różnicę, stworzymy teraz prostą implementację grafu: -```tut +```scala mdoc class Graph { class Node { var connectedNodes: List[Node] = Nil @@ -32,7 +32,7 @@ class Graph { W naszym programie grafy są reprezentowane przez listę wierzchołków. Wierzchołki są obiektami klasy wewnętrznej `Node`. Każdy wierzchołek zawiera listę sąsiadów, które są przechowywane w liście `connectedNodes`. Możemy teraz skonfigurować graf z kilkoma wierzchołkami i połączyć je ze sobą: -```tut +```scala mdoc object GraphTest extends App { val g = new Graph val n1 = g.newNode @@ -45,7 +45,7 @@ object GraphTest extends App { Teraz wzbogacimy nasz przykład o jawne typowanie, aby można było zobaczyć powiązanie typów wierzchołków z grafem: -```tut +```scala mdoc:nest object GraphTest extends App { val g: Graph = new Graph val n1: g.Node = g.newNode @@ -60,7 +60,7 @@ Ten kod pokazuje, że typ wierzchołka jest prefiksowany przez swoją zewnętrzn Przykład niedopuszczalnego programu: -```tut:fail +```scala mdoc:fail object IllegalGraphTest extends App { val g: Graph = new Graph val n1: g.Node = g.newNode @@ -74,7 +74,7 @@ object IllegalGraphTest extends App { Warto zwrócić uwagę na to, że ostatnia linia poprzedniego przykładu byłaby poprawnym programem w Javie. Dla wierzchołków obu grafów Java przypisałaby ten sam typ `Graph.Node`. W Scali także istnieje możliwość wyrażenia takiego typu, zapisując go w formie: `Graph#Node`. Jeżeli byśmy chcieli połączyć wierzchołki różnych grafów, musielibyśmy wtedy zmienić definicję implementacji naszego grafu w następujący sposób: -```tut +```scala mdoc:nest class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil diff --git a/_pl/tour/lower-type-bounds.md b/_pl/tour/lower-type-bounds.md index 093f66214f..c1a166b414 100644 --- a/_pl/tour/lower-type-bounds.md +++ b/_pl/tour/lower-type-bounds.md @@ -13,7 +13,7 @@ Podczas gdy [górne ograniczenia typów](upper-type-bounds.html) zawężają typ Oto przykład, w którym jest to użyteczne: -```tut +```scala mdoc case class ListNode[T](h: T, t: ListNode[T]) { def head: T = h def tail: ListNode[T] = t @@ -24,13 +24,13 @@ case class ListNode[T](h: T, t: ListNode[T]) { Powyższy program implementuje listę jednokierunkową z operacją dodania elementu na jej początek. Niestety typ ten jest niezmienny według parametru typu klasy `ListNode`, tzn. `ListNode[String]` nie jest podtypem `ListNode[Any]`. Z pomocą [adnotacji wariancji](variances.html) możemy wyrazić semantykę podtypowania: -``` +```scala case class ListNode[+T](h: T, t: ListNode[T]) { ... } ``` Niestety ten program się nie skompiluje, ponieważ adnotacja kowariancji może być zastosowana tylko, jeżeli zmienna typu jest używana wyłącznie w pozycji kowariantnej. Jako że zmienna typu `T` występuje jako parametr typu metody `prepend`, ta zasada jest złamana. Z pomocą *dolnego ograniczenia typu* możemy jednak zaimplementować tą metodę w taki sposób, że `T` występuje tylko w pozycji kowariantnej: -```tut +```scala mdoc:nest case class ListNode[+T](h: T, t: ListNode[T]) { def head: T = h def tail: ListNode[T] = t @@ -43,7 +43,7 @@ _Uwaga:_ nowa wersja metody `prepend` ma mniej ograniczający typ. Przykładowo Przykład, który to ilustruje: -```tut +```scala mdoc:fail object LowerBoundTest extends App { val empty: ListNode[Null] = ListNode(null, null) val strList: ListNode[String] = empty.prepend("hello") diff --git a/_pl/tour/mixin-class-composition.md b/_pl/tour/mixin-class-composition.md index 5dcff46652..dc7ad8dc4e 100644 --- a/_pl/tour/mixin-class-composition.md +++ b/_pl/tour/mixin-class-composition.md @@ -12,7 +12,7 @@ previous-page: tuples Domieszka (ang. mixin) to cecha (trait), która używana jest do komponowania klas. {% scalafiddle %} -```tut +```scala mdoc abstract class A { val message: String } @@ -36,7 +36,7 @@ Domieszki i nadklasy mogą posiadać tą samą nadklasę (typ bazowy). Spójrzmy teraz na trochę ciekawszy przykład zawierający klasę abstrakcyjną. -```tut +```scala mdoc abstract class AbsIterator { type T def hasNext: Boolean @@ -46,7 +46,7 @@ abstract class AbsIterator { Klasa ta zawiera abstrakcyjny typ `type T` oraz standardowe metody iteracyjne `hasNext` i `next`. -```tut +```scala mdoc class StringIterator(s: String) extends AbsIterator { type T = Char private var i = 0 @@ -63,7 +63,7 @@ Klasa `StringIterator` przyjmuje parametr typu `String`, może być ona użyta d Stwórzmy teraz cechę, która również rozszerza `AbsIterator`. -```tut +```scala mdoc trait RichIterator extends AbsIterator { def foreach(f: T => Unit): Unit = while (hasNext) f(next()) } @@ -74,7 +74,7 @@ Ponieważ `RichIterator` jest cechą, nie musi implementować abstrakcyjnych sk Spróbujmy teraz połączyć funkcjonalności `StringIterator` oraz `RichIterator` w jednej klasie. -```tut +```scala mdoc object StringIteratorTest extends App { class RichStringIter extends StringIterator("Scala") with RichIterator val richStringIter = new RichStringIter diff --git a/_pl/tour/multiple-parameter-lists.md b/_pl/tour/multiple-parameter-lists.md index cae31b0fa2..9bb9e100c5 100644 --- a/_pl/tour/multiple-parameter-lists.md +++ b/_pl/tour/multiple-parameter-lists.md @@ -24,7 +24,7 @@ Poniżej omówiony jest przykład użycia. Zaczynając od początkowej wartości 0, funkcja `foldLeft` stosuje funkcję `(m, n) => m + n` na każdym elemencie listy oraz poprzedniej zakumulowanej wartości. {% scalafiddle %} -```tut +```scala mdoc val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val res = numbers.foldLeft(0)((m, n) => m + n) println(res) // 55 @@ -52,7 +52,7 @@ numbers.foldLeft(0)(_ + _) Powyższe wyrażenie `numbers.foldLeft(0)(_ + _)` pozwala trwale ustawić parametr `z` i przekazywać dalej częściową funkcję (partial function), tak jak pokazano to poniżej: -```tut +```scala mdoc:nest val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val numberFunc = numbers.foldLeft(List[Int]())_ @@ -65,7 +65,7 @@ print(cubes.toString()) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000) Podsumowując, `foldLeft` oraz `foldRight` mogą być używane w dowolnej z poniższych postaci: -```tut +```scala mdoc:nest val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) numbers.foldLeft(0)((sum, item) => sum + item) // postać ogólna diff --git a/_pl/tour/named-arguments.md b/_pl/tour/named-arguments.md index 0e3f4965f9..bf297d982d 100644 --- a/_pl/tour/named-arguments.md +++ b/_pl/tour/named-arguments.md @@ -11,7 +11,7 @@ previous-page: default-parameter-values Wywołując metody i funkcje, możesz użyć nazwy parametru jawnie podczas wywołania: -```tut +```scala mdoc def printName(first:String, last:String) = { println(first + " " + last) } @@ -23,7 +23,7 @@ printName(last = "Smith", first = "John") // Wypisuje "John Smith" Warto zwrócić uwagę na to, że kolejność wyboru parametrów podczas wywołania nie ma znaczenia, dopóki wszystkie parametry są nazwane. Ta funkcjonalność jest dobrze zintegrowana z [domyślnymi wartościami parametrów](default-parameter-values.html): -```tut +```scala mdoc:nest def printName(first: String = "John", last: String = "Smith") = { println(first + " " + last) } diff --git a/_pl/tour/nested-functions.md b/_pl/tour/nested-functions.md index a384b0a449..1531854082 100644 --- a/_pl/tour/nested-functions.md +++ b/_pl/tour/nested-functions.md @@ -13,7 +13,7 @@ Scala pozwala na zagnieżdżanie definicji funkcji. Poniższy obiekt określa funkcję `factorial`, która oblicza silnię dla danej liczby: {% scalafiddle %} -```tut +```scala mdoc def factorial(x: Int): Int = { def fact(x: Int, accumulator: Int): Int = { if (x <= 1) accumulator diff --git a/_pl/tour/operators.md b/_pl/tour/operators.md index bbdacf2cd7..8730570849 100644 --- a/_pl/tour/operators.md +++ b/_pl/tour/operators.md @@ -11,7 +11,7 @@ previous-page: type-inference Każda metoda, która przyjmuje jeden parametr, może być użyta jako *operator infiksowy*. Oto definicja klasy `MyBool` która zawiera metody `and` i `or`: -```tut +```scala mdoc case class MyBool(x: Boolean) { def and(that: MyBool): MyBool = if (x) that else this def or(that: MyBool): MyBool = if (x) this else that @@ -21,7 +21,7 @@ case class MyBool(x: Boolean) { Można teraz użyć `and` i `or` jako operatory infiksowe: -```tut +```scala mdoc def not(x: MyBool) = x.negate def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y) ``` @@ -30,7 +30,7 @@ Można zauważyć, że dzięki zastosowaniu operatorów infiksowych metoda `xor` Dla porównania, oto kod który nie wykorzystuje operatorów infiksowych: -```tut +```scala mdoc:nest def not(x: MyBool) = x.negate def xor(x: MyBool, y: MyBool) = x.or(y).and(x.and(y).negate) ``` diff --git a/_pl/tour/packages-and-imports.md b/_pl/tour/packages-and-imports.md index 30702a4850..9bcdb38fc1 100644 --- a/_pl/tour/packages-and-imports.md +++ b/_pl/tour/packages-and-imports.md @@ -74,7 +74,7 @@ import users.{UserPreferences => UPrefs} // zaimportuj i zmień nazwę dla wygo Jedną z różnic w Scali od Javy jest to, że deklarację `import` można umieścić w dowolnym miejscu: -```tut +```scala mdoc def sqrtplus1(x: Int) = { import scala.math.sqrt sqrt(x) + 1.0 diff --git a/_pl/tour/pattern-matching.md b/_pl/tour/pattern-matching.md index 0d9a5dd8fd..3b853bff1b 100644 --- a/_pl/tour/pattern-matching.md +++ b/_pl/tour/pattern-matching.md @@ -11,7 +11,7 @@ previous-page: case-classes Scala posiada wbudowany mechanizm dopasowania wzorców. Umożliwia on dopasowanie dowolnego rodzaju danych, przy czym zawsze zwracamy pierwsze dopasowanie. Przykład dopasowania liczby całkowitej: -```tut +```scala mdoc object MatchTest1 extends App { def matchTest(x: Int): String = x match { case 1 => "one" @@ -26,7 +26,7 @@ Blok kodu z wyrażeniami `case` definiuje funkcję, która przekształca liczby Wzorce można także dopasowywać do różnych typów wartości: -```tut +```scala mdoc object MatchTest2 extends App { def matchTest(x: Any): Any = x match { case 1 => "one" diff --git a/_pl/tour/polymorphic-methods.md b/_pl/tour/polymorphic-methods.md index 55b16d0023..113887aeee 100644 --- a/_pl/tour/polymorphic-methods.md +++ b/_pl/tour/polymorphic-methods.md @@ -13,7 +13,7 @@ Metody w Scali mogą być parametryzowane zarówno przez wartości, jak i typy. Przykład poniżej: -```tut +```scala mdoc def dup[T](x: T, n: Int): List[T] = { if (n == 0) Nil diff --git a/_pl/tour/regular-expression-patterns.md b/_pl/tour/regular-expression-patterns.md index 22701d0644..9d8efe1cba 100644 --- a/_pl/tour/regular-expression-patterns.md +++ b/_pl/tour/regular-expression-patterns.md @@ -20,7 +20,7 @@ Elem(prefix:String, label:String, attrs:MetaData, scp:NamespaceBinding, children W tych przypadkach Scala pozwala wzorcom na zastosowanie symbolu `_*` w ostatniej pozycji, aby dopasować sekwencje dowolnej długości. Poniższy przykład demonstruje dopasowanie wzorca, który rozpoznaje początek sekwencji i wiąże resztę do zmiennej `rest`: -```tut +```scala mdoc object RegExpTest1 extends App { def containsScala(x: String): Boolean = { val z: Seq[Char] = x diff --git a/_pl/tour/self-types.md b/_pl/tour/self-types.md index 2c9008a83d..1bbb74be98 100644 --- a/_pl/tour/self-types.md +++ b/_pl/tour/self-types.md @@ -13,7 +13,7 @@ Dążąc do tego, aby nasze oprogramowanie było rozszerzalne, często przydatne Oto definicja opisująca grafy: -```tut +```scala mdoc abstract class Graph { type Edge type Node <: NodeIntf @@ -30,7 +30,7 @@ Grafy składają się z listy węzłów oraz krawędzi, gdzie zarówno typ węz Przykład implementacji klasy `Graph`: -```tut:fail +```scala mdoc:fail abstract class DirectedGraph extends Graph { type Edge <: EdgeImpl class EdgeImpl(origin: Node, dest: Node) { @@ -64,7 +64,7 @@ Jeżeli przyjrzymy się bliżej implementacji metody `connectWith`, możemy dost Scala rozwiązuje ten problem pozwalając na powiązanie klasy z innym typem poprzez jawne typowanie samoreferencji. Możemy użyć tego mechanizmu, aby naprawić powyższy kod: -```tut +```scala mdoc abstract class DirectedGraph extends Graph { type Edge <: EdgeImpl class EdgeImpl(origin: Node, dest: Node) { @@ -95,7 +95,7 @@ W nowej definicji klasy `NodeImpl` referencja `this` jest typu `Node`. Ponieważ Oto konkretna specjalizacja `DirectedGraph`, gdzie abstrakcyjne elementy klasy mają ustalone ścisłe znaczenie: -```tut +```scala mdoc class ConcreteDirectedGraph extends DirectedGraph { type Edge = EdgeImpl type Node = NodeImpl @@ -109,7 +109,7 @@ Należy dodać, że w tej klasie możemy utworzyć `NodeImpl`, ponieważ wiemy j Poniżej przykład zastosowania klasy `ConcreteDirectedGraph`: -```tut +```scala mdoc object GraphTest extends App { val g: Graph = new ConcreteDirectedGraph val n1 = g.addNode diff --git a/_pl/tour/singleton-objects.md b/_pl/tour/singleton-objects.md index c248da92a6..14529d8993 100644 --- a/_pl/tour/singleton-objects.md +++ b/_pl/tour/singleton-objects.md @@ -31,7 +31,7 @@ Duża część obiektów singleton nie istnieje samodzielnie, ale jest powiązan Klasa i jej obiekt towarzyszący mogą być zdefiniowane tylko w tym samym pliku, przykład: -```tut +```scala mdoc class IntPair(val x: Int, val y: Int) object IntPair { diff --git a/_pl/tour/traits.md b/_pl/tour/traits.md index 032423ea0a..4751e0824d 100644 --- a/_pl/tour/traits.md +++ b/_pl/tour/traits.md @@ -18,13 +18,13 @@ Z tego powodu cechy nie przyjmują parametrów wartości. Minimalna definicja cechy składa się ze słowa kluczowego `trait` oraz identyfikatora. -```tut +```scala mdoc trait HairColor ``` Cechy są szczególnie przydatne jako generyczne typy zawierające abstrakcyjne metody. -```tut +```scala mdoc trait Iterator[A] { def hasNext: Boolean def next(): A @@ -39,7 +39,7 @@ Aby rozszerzyć cechę należy użyć słowa kluczowego `extends`. Następnie wymagane jest zaimplementowanie abstrakcyjnych składników danej cechy używając słowa kluczowego `override.` {% scalafiddle %} -```tut +```scala mdoc:nest trait Iterator[A] { def hasNext: Boolean def next(): A @@ -70,7 +70,7 @@ Klasa `IntIterator` przyjmuje parametr `to` (do) jako ograniczenie górne, oraz Jeżeli w jakimś miejscu wymagana jest cecha pewnego typu, to zamiast niej można użyć jej podtypu. {% scalafiddle %} -```tut +```scala mdoc import scala.collection.mutable.ArrayBuffer trait Pet { diff --git a/_pl/tour/tuples.md b/_pl/tour/tuples.md index 9973e42e20..b415c1a348 100644 --- a/_pl/tour/tuples.md +++ b/_pl/tour/tuples.md @@ -17,7 +17,7 @@ Krotki przydają się, gdy chcemy, żeby funkcja zwróciła jednocześnie wiele Krotki tworzy się w następujący sposób: -```tut +```scala mdoc val ingredient = ("Sugar" , 25): Tuple2[String, Int] ``` @@ -32,7 +32,7 @@ W ww. przykładzie jest to `Tuple2[String, Int]`. Krotka zapewnia dostęp do swoich elementów z użyciem składni podkreślnika (underscore). `tuple._n` odwołuje się do n-tego elementu w kolejności (pod warunkiem, że dana krotka zawiera tyle elementów). -```tut +```scala mdoc println(ingredient._1) // wyświetli Sugar println(ingredient._2) // wyświetli 25 @@ -42,7 +42,7 @@ println(ingredient._2) // wyświetli 25 Krotki w Scali wspierają dekonstrukcję -```tut +```scala mdoc val (name, quantity) = ingredient println(name) // wyświetli Sugar @@ -53,7 +53,7 @@ println(quantity) // wyświetli 25 Dekonstrukcja krotek może być bardzo przydatna w dopasowywaniu wzorców (ang. pattern matching) {% scalafiddle %} -```tut +```scala mdoc val planetDistanceFromSun = List( ("Mercury", 57.9), ("Venus", 108.2), @@ -74,7 +74,7 @@ planetDistanceFromSun.foreach { Ma ona też zastosowanie w wyrażeniach 'for'. {% scalafiddle %} -```tut +```scala mdoc val numPairs = List((2, 5), (3, -7), (20, 56)) for ((a, b) <- numPairs) { diff --git a/_pl/tour/type-inference.md b/_pl/tour/type-inference.md index 4c5435eb63..f7f0d42055 100644 --- a/_pl/tour/type-inference.md +++ b/_pl/tour/type-inference.md @@ -13,7 +13,7 @@ Scala posiada wbudowany mechanizm inferencji typów, który pozwala programiści Oto przykład: -```tut +```scala mdoc object InferenceTest1 extends App { val x = 1 + 2 * 3 // typem x jest Int val y = x.toString() // typem y jest String @@ -23,7 +23,7 @@ object InferenceTest1 extends App { Dla metod rekurencyjnych kompilator nie jest w stanie określić zwracanego typu. Oto przykład programu, który zakończy się niepowodzeniem kompilacji z tego powodu: -```tut:fail +```scala mdoc:fail object InferenceTest2 { def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) } @@ -51,7 +51,7 @@ val y: Int = id[Int](1) W niektórych sytuacjach poleganie na inferencji typów w Scali może być niebezpieczne, tak jak demonstruje to poniższy program: -```tut:fail +```scala mdoc:fail object InferenceTest4 { var obj = null obj = new Object() diff --git a/_pl/tour/unified-types.md b/_pl/tour/unified-types.md index c58618a781..e93d2e893b 100644 --- a/_pl/tour/unified-types.md +++ b/_pl/tour/unified-types.md @@ -36,7 +36,7 @@ Jeżeli Scala użyta jest w kontekście środowiska uruchomieniowego Javy, to `A Poniższy przykład pokazuje, że łańcuchy znakowe, liczby całkowite, znaki, wartości logiczne oraz funkcje są obiektami tak samo jak każdy inny obiekt: {% scalafiddle %} -```tut +```scala mdoc val list: List[Any] = List( "Łancuch znaków", 732, // liczba całkowita @@ -70,7 +70,7 @@ Typy wartości mogą być rzutowane w następujący sposób: Dla przykładu: -```tut +```scala mdoc val x: Long = 987654321 val y: Float = x // 9.8765434E8 (w tym wypadku tracimy część precyzji) diff --git a/_pl/tour/upper-type-bounds.md b/_pl/tour/upper-type-bounds.md index 1792e9e3b1..e9e801cd66 100644 --- a/_pl/tour/upper-type-bounds.md +++ b/_pl/tour/upper-type-bounds.md @@ -13,7 +13,7 @@ W Scali [parametry typów](generic-classes.html) oraz [typy abstrakcyjne](abstra Poniższy przykład demonstruje zastosowanie ograniczeń górnych typu dla parametru typu klasy `Cage`: -```tut +```scala mdoc abstract class Animal { def name: String } diff --git a/_pl/tour/variances.md b/_pl/tour/variances.md index 2efc1a7638..db0e485413 100644 --- a/_pl/tour/variances.md +++ b/_pl/tour/variances.md @@ -13,7 +13,7 @@ Scala wspiera adnotacje wariancji parametrów typów [klas generycznych](generic Na stronie o [klasach generycznych](generic-classes.html) omówiliśmy przykład zmiennego stosu. Wyjaśniliśmy, że typ definiowany przez klasę `Stack[T]` jest poddany niezmiennemu podtypowaniu w stosunku do parametru typu. Może to ograniczyć możliwość ponownego wykorzystania abstrakcji tej klasy. Spróbujemy teraz opracować funkcyjną (tzn. niemutowalną) implementację dla stosów, które nie posiadają tego ograniczenia. Warto zwrócić uwagę, że jest to zaawansowany przykład łączący w sobie zastosowanie [funkcji polimorficznych](polymorphic-methods.html), [dolnych ograniczeń typu](lower-type-bounds.html) oraz kowariantnych adnotacji parametru typu. Dodatkowo stosujemy też [klasy wewnętrzne](inner-classes.html), aby połączyć ze sobą elementy stosu bez jawnych powiązań. -```tut +```scala mdoc class Stack[+T] { def push[S >: T](elem: S): Stack[S] = new Stack[S] { override def top: S = elem diff --git a/_plugins/mdoc_replace.rb b/_plugins/mdoc_replace.rb new file mode 100644 index 0000000000..0b62828227 --- /dev/null +++ b/_plugins/mdoc_replace.rb @@ -0,0 +1,22 @@ +module Jekyll + class MdocConverter < Converter + safe false + priority :high + + def matches(ext) + ext =~ /^\.(md|markdown)$/i + end + + def output_ext(ext) + ".html" + end + + def convert(content) + content = content.gsub("```scala mdoc:fail\n", "```scala\n") + content = content.gsub("```scala mdoc:crash\n", "```scala\n") + content = content.gsub("```scala mdoc:nest\n", "```scala\n") + content = content.gsub("```scala mdoc:reset\n", "```scala\n") + content.gsub("```scala mdoc\n", "```scala\n") + end + end +end diff --git a/_plugins/tut_replace.rb b/_plugins/tut_replace.rb deleted file mode 100644 index 06ee3c7fe9..0000000000 --- a/_plugins/tut_replace.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Jekyll - class TutConverter < Converter - safe false - priority :high - - def matches(ext) - ext =~ /^\.(md|markdown)$/i - end - - def output_ext(ext) - ".html" - end - - def convert(content) - content = content.gsub("```tut:fail\n", "```scala\n") - content = content.gsub("```tut:nofail\n", "```scala\n") - content.gsub("```tut\n", "```scala\n") - end - end -end diff --git a/_pt-br/tour/abstract-type-members.md b/_pt-br/tour/abstract-type-members.md index 4bca7396dc..8a798f4468 100644 --- a/_pt-br/tour/abstract-type-members.md +++ b/_pt-br/tour/abstract-type-members.md @@ -13,7 +13,7 @@ Em Scala, as classes são parametrizadas com valores (os parâmetros de construt Aqui está um exemplo que mostra uma definição de valor diferido e uma definição de tipo abstrato como membros de uma [trait](traits.html) chamada `Buffer`. -```tut +```scala mdoc trait Buffer { type T val element: T @@ -24,7 +24,7 @@ trait Buffer { No seguinte programa temos uma classe `SeqBuffer` que nos permite armazenar apenas as sequências no buffer ao definir que o tipo `T` precisa ser um subtipo de `Seq[U]` para um novo tipo abstrato `U`: -```tut +```scala mdoc abstract class SeqBuffer extends Buffer { type U type T <: Seq[U] @@ -34,7 +34,7 @@ abstract class SeqBuffer extends Buffer { [Traits](traits.html) ou [classes](classes.html) com membros de tipo abstratos são frequentemente utilizadas em combinação com instâncias de classe anônimas. Para ilustrar isso, agora analisamos um programa que lida com um buffer de sequência que se refere a uma lista de inteiros: -```tut +```scala mdoc abstract class IntSeqBuffer extends SeqBuffer { type U = Int } @@ -55,22 +55,20 @@ O tipo de retorno do método `newIntSeqBuf` refere-se a uma especialização da Observe que muitas vezes é possível transformar os membros de tipo abstrato em parâmetros de tipo de classes e vice-versa. Aqui está uma versão do código acima que usa apenas parâmetros de tipo: -```tut +```scala mdoc:nest abstract class Buffer[+T] { val element: T } abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] { def length = element.length } -object AbstractTypeTest2 extends App { - def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] = - new SeqBuffer[Int, List[Int]] { - val element = List(e1, e2) - } - val buf = newIntSeqBuf(7, 8) - println("length = " + buf.length) - println("content = " + buf.element) -} +def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] = + new SeqBuffer[Int, List[Int]] { + val element = List(e1, e2) + } +val buf = newIntSeqBuf(7, 8) +println("length = " + buf.length) +println("content = " + buf.element) ``` Note que temos que usar [anotação de variância](variances.html) aqui; Caso contrário, não seríamos capazes de ocultar o tipo implementado pela sequência concreta do objeto retornado pelo método `newIntSeqBuf`. Além disso, há casos em que não é possível substituir tipos abstratos com parâmetros de tipo. diff --git a/_pt-br/tour/automatic-closures.md b/_pt-br/tour/automatic-closures.md index a16bec7160..2f9072a59d 100644 --- a/_pt-br/tour/automatic-closures.md +++ b/_pt-br/tour/automatic-closures.md @@ -15,7 +15,7 @@ Scala permite funções sem parâmetros como parâmetros de métodos. Quando um O código a seguir demonstra esse mecanismo: -```tut +```scala mdoc object TargetTest1 extends App { def whileLoop(cond: => Boolean)(body: => Unit): Unit = if (cond) { @@ -36,7 +36,7 @@ Podemos combinar o uso de [operadores infix/postfix](operators.html) com este me Aqui está a implementação de uma instrução que executa loop a menos que uma condição seja satisfeita: -```tut +```scala mdoc object TargetTest2 extends App { def loop(body: => Unit): LoopUnlessCond = new LoopUnlessCond(body) diff --git a/_pt-br/tour/case-classes.md b/_pt-br/tour/case-classes.md index 16886891e3..5524865ee6 100644 --- a/_pt-br/tour/case-classes.md +++ b/_pt-br/tour/case-classes.md @@ -18,7 +18,7 @@ Scala suporta o conceito de _classes case_. Classes case são classes regulares Aqui temos um exemplo de hierarquia de tipos para *Notification* que consiste em uma super classe abstrata `Notification` e três tipos concretos de notificação implementados com classes case `Email`, `SMS`, e `VoiceRecording`. -```tut +```scala mdoc abstract class Notification case class Email(sourceEmail: String, title: String, body: String) extends Notification case class SMS(sourceNumber: String, message: String) extends Notification @@ -27,26 +27,26 @@ case class VoiceRecording(contactName: String, link: String) extends Notificatio Instânciar uma classe case é fácil: (Perceba que nós não precisamos da palavra-chave `new`) -```tut +```scala mdoc val emailDeJohn = Email("john.doe@mail.com", "Saudações do John!", "Olá Mundo") ``` Os parâmetros do construtor de uma classe case são tratados como valores públicos e podem ser acessados diretamente. -```tut +```scala mdoc val titulo = emailDeJohn.title println(titulo) // prints "Saudações do John!" ``` Com classes case, você não pode alterar seus campos diretamente. (ao menos que você declare `var` antes de um campo, mas fazê-lo geralmente é desencorajado). -```tut:fail +```scala mdoc:fail emailDeJohn.title = "Adeus do John!" // Erro the compilação. Não podemos atribuir outro valor para um campo que foi declarado como val, lembrando que todos os campos de classes case são val por padrão. ``` Ao invés disso, faça uma cópia utilizando o método `copy`. Como descrito abaixo, então você poderá substituir alguns dos campos: -```tut +```scala mdoc val emailEditado = emailDeJohn.copy(title = "Estou aprendendo Scala!", body = "É muito legal!") println(emailDeJohn) // prints "Email(john.doe@mail.com,Saudações do John!,Hello World!)" @@ -55,7 +55,7 @@ println(emailEditado) // prints "Email(john.doe@mail.com,Estou aprendendo Scala, Para cada classe case em Scala o compilador gera um método `equals` que implementa a igualdade estrutural e um método `toString`. Por exemplo: -```tut +```scala mdoc val primeiroSMS = SMS("12345", "Hello!") val segundoSMS = SMS("12345", "Hello!") @@ -75,7 +75,7 @@ SMS é: SMS(12345, Hello!) Com classes case, você pode utilizar **correspondência de padrões** para manipular seus dados. Aqui temos um exemplo de uma função que escreve como saída diferente mensagens dependendo do tipo de notificação recebida: -```tut +```scala mdoc def mostrarNotificacao(notificacao: Notification): String = { notificacao match { case Email(email, title, _) => @@ -96,7 +96,7 @@ println(mostrarNotificacao(algumaMsgVoz)) // Saída "Você recebeu uma Mensagem Aqui um exemplo mais elaborado utilizando a proteção `if`. Com a proteção `if`, o correspondência de padrão irá falhar se a condição de proteção retorna falso. -```tut +```scala mdoc:nest def mostrarNotificacaoEspecial(notificacao: Notification, emailEspecial: String, numeroEspecial: String): String = { notificacao match { case Email(email, _, _) if email == emailEspecial => diff --git a/_pt-br/tour/classes.md b/_pt-br/tour/classes.md index 9861271a36..26a49fc55e 100644 --- a/_pt-br/tour/classes.md +++ b/_pt-br/tour/classes.md @@ -12,7 +12,7 @@ language: pt-br Classes em Scala são templates estáticos que podem ser instanciados como vários objetos em tempo de execução. Aqui uma definição de classe que define a classe `Ponto`: -```tut +```scala mdoc class Ponto(var x: Int, var y: Int) { def move(dx: Int, dy: Int): Unit = { x = x + dx @@ -31,7 +31,7 @@ Perceba que em Scala, não é necessário declarar `return` para então retornar Classes são instânciadas com a primitiva `new`, por exemplo: -```tut +```scala mdoc object Classes { def main(args: Array[String]) { val pt = new Ponto(1, 2) diff --git a/_pt-br/tour/compound-types.md b/_pt-br/tour/compound-types.md index d648fa319a..7465bdebb4 100644 --- a/_pt-br/tour/compound-types.md +++ b/_pt-br/tour/compound-types.md @@ -13,7 +13,7 @@ language: pt-br Suponha que temos duas traits `Cloneable` and `Resetable`: -```tut +```scala mdoc trait Cloneable extends java.lang.Cloneable { override def clone(): Cloneable = { super.clone().asInstanceOf[Cloneable] diff --git a/_pt-br/tour/default-parameter-values.md b/_pt-br/tour/default-parameter-values.md index 898eca8b0d..197ca5c058 100644 --- a/_pt-br/tour/default-parameter-values.md +++ b/_pt-br/tour/default-parameter-values.md @@ -50,7 +50,7 @@ Enquanto isso nos impede de nos repetir, é menos do que expressivo. Scala adiciona suporte direto para isso: -```tut +```scala mdoc class HashMap[K,V](initialCapacity:Int = 16, loadFactor:Float = 0.75f) { } diff --git a/_pt-br/tour/extractor-objects.md b/_pt-br/tour/extractor-objects.md index 9dd9e21e11..e91788ee9f 100644 --- a/_pt-br/tour/extractor-objects.md +++ b/_pt-br/tour/extractor-objects.md @@ -11,7 +11,7 @@ language: pt-br Em Scala, padrões podem ser definidos independentemente de classes case. Para este fim, um método chamado `unapply` é definido para retornar um extrator. Um extrator pode ser pensado como um método especial que inverte o efeito da aplicação de um determinado objeto em algumas entradas. Seu objetivo é "extrair" as entradas que estavam presentes antes da operação `apply`. Por exemplo, o código a seguir define um [objeto](singleton-objects.html) extrator chamado Twice. -```tut +```scala mdoc object Twice { def apply(x: Int): Int = x * 2 def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z/2) else None diff --git a/_pt-br/tour/generic-classes.md b/_pt-br/tour/generic-classes.md index 82234c4636..d6e72103a0 100644 --- a/_pt-br/tour/generic-classes.md +++ b/_pt-br/tour/generic-classes.md @@ -12,7 +12,7 @@ language: pt-br Semelhante ao Java 5 (aka. JDK 1.5), Scala tem suporte nativo para classes parametrizadas com tipos. Essas classes genéricas são particularmente úteis para o desenvolvimento de classes que representam coleções de dados. Aqui temos um exemplo que demonstra isso: -```tut +```scala mdoc class Stack[T] { var elems: List[T] = Nil def push(x: T) { elems = x :: elems } @@ -25,7 +25,7 @@ A classe `Stack` modela uma pilha mutável que contém elementos de um tipo arbi Aqui temos mais alguns exemplos de uso: -```tut +```scala mdoc object GenericsTest extends App { val stack = new Stack[Int] stack.push(1) diff --git a/_pt-br/tour/higher-order-functions.md b/_pt-br/tour/higher-order-functions.md index eaba32861c..f71baf9e67 100644 --- a/_pt-br/tour/higher-order-functions.md +++ b/_pt-br/tour/higher-order-functions.md @@ -11,7 +11,7 @@ language: pt-br Scala permite definir funções de ordem superior. Tais funções _recebem outras funções como parâmetros_, ou _resultam em uma função_. Por exemplo, a função `apply` recebe outra função `f` e um valor `v` então aplica a função `f` em`v`: -```tut +```scala mdoc def apply(f: Int => String, v: Int) = f(v) ``` @@ -19,13 +19,13 @@ _Nota: métodos são automaticamente convertidos em funções se o contexto dema Outro exemplo: -```tut +```scala mdoc class Decorator(left: String, right: String) { def layout[A](x: A) = left + x.toString() + right } object FunTest extends App { - def apply(f: Int => String, v: Int) = f(v) + override def apply(f: Int => String, v: Int) = f(v) val decorator = new Decorator("[", "]") println(apply(decorator.layout, 7)) } diff --git a/_pt-br/tour/implicit-conversions.md b/_pt-br/tour/implicit-conversions.md index c8ee38d23b..cc96f99062 100644 --- a/_pt-br/tour/implicit-conversions.md +++ b/_pt-br/tour/implicit-conversions.md @@ -41,7 +41,7 @@ O objeto implicitamente importado `scala.Predef` declara vários tipos predefini Por exemplo, ao chamar um método Java que espera um `java.lang.Integer`, você está livre para passar um `scala.Int` em vez disso. Isso ocorre porque `Predef` inclui as seguintes conversões implícitas: -```tut +```scala mdoc import scala.language.implicitConversions implicit def int2Integer(x: Int) = diff --git a/_pt-br/tour/implicit-parameters.md b/_pt-br/tour/implicit-parameters.md index e963c4b9e3..7f1f0d0a98 100644 --- a/_pt-br/tour/implicit-parameters.md +++ b/_pt-br/tour/implicit-parameters.md @@ -19,7 +19,7 @@ Os argumentos reais que são elegíveis para serem passados para um parâmetro i No exemplo a seguir, definimos um método `sum` que calcula a soma de uma lista de elementos usando as operações `add` e `unit` do monoide. Observe que valores implícitos não podem ser *top-level*, eles precisam ser membros de um modelo. -```tut +```scala mdoc /** Este exemplo usa uma estrutura da álgebra abstrata para mostrar como funcionam os parâmetros implícitos. Um semigrupo é uma estrutura algébrica em um conjunto A com uma operação (associativa), chamada add, que combina um par de A's e retorna um outro A. */ abstract class SemiGroup[A] { def add(x: A, y: A): A diff --git a/_pt-br/tour/inner-classes.md b/_pt-br/tour/inner-classes.md index dbcbe4c93e..aff2633035 100644 --- a/_pt-br/tour/inner-classes.md +++ b/_pt-br/tour/inner-classes.md @@ -11,7 +11,7 @@ language: pt-br Em Scala é possível declarar classes que tenham outras classes como membros. Em contraste com a linguagenm Java, onde classes internas são membros da classe em que foram declaradas, em Scala as classes internas são ligadas ao objeto exterior. Para ilustrar essa diferença, rapidamente esboçamos a implementação de grafo como um tipo de dados: -```tut +```scala mdoc class Graph { class Node { var connectedNodes: List[Node] = Nil @@ -32,7 +32,7 @@ class Graph { Em nosso programa, os grafos são representados por uma lista de nós. Os nós são objetos da classe interna `Node`. Cada nó tem uma lista de vizinhos, que são armazenados na lista `connectedNodes`. Agora podemos configurar um grafo com alguns nós e conectar os nós de forma incremental: -```tut +```scala mdoc object GraphTest extends App { val g = new Graph val n1 = g.newNode @@ -45,7 +45,7 @@ object GraphTest extends App { Agora melhoramos o exemplo acima com tipos, para assim declarar explicitamente qual o tipo das várias entidades definidas: -```tut +```scala mdoc:nest object GraphTest extends App { val g: Graph = new Graph val n1: g.Node = g.newNode @@ -59,7 +59,7 @@ object GraphTest extends App { Este código mostra claramente que o tipo nó é prefixado com sua instância externa (em nosso exemplo é o objeto `g`). Se agora temos dois grafos, o sistema de tipos de Scala não nos permite misturar nós definidos dentro de um grafo com os nós de outro, já que os nós do outro grafo têm um tipo diferente. Aqui está um programa inválido: -```tut:fail +```scala mdoc:fail object IllegalGraphTest extends App { val g: Graph = new Graph val n1: g.Node = g.newNode @@ -73,7 +73,7 @@ object IllegalGraphTest extends App { Observe que em Java a última linha no programa do exemplo anterior é válida. Para nós de ambos os grafos, Java atribuiria o mesmo tipo `Graph.Node`; isto é, `Node` é prefixado com a classe `Graph`. Em Scala, esse tipo também pode ser expresso, e é escrito `Graph#Node`. Se quisermos ser capazes de conectar nós de diferentes grafos, temos que mudar a definição inicial da nossa implementação do grafo da seguinte maneira: -```tut +```scala mdoc:nest class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil diff --git a/_pt-br/tour/lower-type-bounds.md b/_pt-br/tour/lower-type-bounds.md index 7e89933be2..61e5553ec7 100644 --- a/_pt-br/tour/lower-type-bounds.md +++ b/_pt-br/tour/lower-type-bounds.md @@ -13,7 +13,7 @@ Enquanto o [limitante superior de tipos](upper-type-bounds.html) limita um tipo Aqui está um exemplo onde isso é útil: -```tut +```scala mdoc case class ListNode[T](h: T, t: ListNode[T]) { def head: T = h def tail: ListNode[T] = t @@ -24,7 +24,7 @@ case class ListNode[T](h: T, t: ListNode[T]) { O programa acima implementa uma linked list com uma operação de pré-inserção. Infelizmente, esse tipo é invariante no parâmetro de tipo da classe `ListNode`; Ou seja, `ListNode [String]` não é um subtipo de `ListNode [Any]`. Com a ajuda de [anotações de variância](variances.html) podemos expressar tal semântica de subtipo: -``` +```scala case class ListNode[+T](h: T, t: ListNode[T]) { ... } ``` @@ -32,7 +32,7 @@ Infelizmente, este programa não compila, porque uma anotação de covariância Aqui está o código correspondente: -```tut +```scala mdoc:reset case class ListNode[+T](h: T, t: ListNode[T]) { def head: T = h def tail: ListNode[T] = t @@ -45,7 +45,7 @@ _Nota:_ o novo método `prepend` tem um tipo ligeiramente menos restritivo. Perm Aqui está o código que ilustra isso: -```tut +```scala object LowerBoundTest extends App { val empty: ListNode[Null] = ListNode(null, null) val strList: ListNode[String] = empty.prepend("hello") diff --git a/_pt-br/tour/mixin-class-composition.md b/_pt-br/tour/mixin-class-composition.md index 2f830f6b8b..80002a731a 100644 --- a/_pt-br/tour/mixin-class-composition.md +++ b/_pt-br/tour/mixin-class-composition.md @@ -12,7 +12,7 @@ _Nota de tradução: A palavra `mixin` pode ser traduzida como mescla, porém é Ao contrário de linguagens que suportam somente _herança simples_, Scala tem uma noção mais abrangente sobre a reutilização de classes. Scala torna possível reutilizar a _nova definição de membros de uma classe_ (por exemplo: o relacionamento delta para com a superclasse) na definição de uma nova classe. Isso é expressado como uma _composição de classe mixin ou mixin-class composition_. Considere a seguinte abstração para iterators. -```tut +```scala mdoc abstract class AbsIterator { type T def hasNext: Boolean @@ -22,7 +22,7 @@ abstract class AbsIterator { A seguir, considere a classe mixin que estende `AbsIterator` com um método `foreach` que aplica uma dada função para cada elemento retornado pelo iterator. Para definir tal classe que será utilizada como um mixin a palavra-chave `trait` deve ser declarada. -```tut +```scala mdoc trait RichIterator extends AbsIterator { def foreach(f: T => Unit) { while (hasNext) f(next()) } } @@ -30,7 +30,7 @@ trait RichIterator extends AbsIterator { Aqui uma classes iterator concreta a qual retorna sucessivos caracteres de uma dada string: -```tut +```scala mdoc class StringIterator(s: String) extends AbsIterator { type T = Char private var i = 0 @@ -41,7 +41,7 @@ class StringIterator(s: String) extends AbsIterator { Poderíamos combinar a funcionalidade de `StringIterator` e `RichIterator` em uma só classe. Com herança simples e interfaces isso é impossível, pois ambas as classes contém implementações para seus membros. Scala nos ajuda com a sua _composição de classes mixin_. Isso permite que programadores reutilizem o delta de uma definição de uma classe, por exemplo: todas as novas definições não são herdadas. Esse mecanismo torna possível combinar `StringIterator` com `RichIterator`, como pode ser visto no programa teste a seguir, que imprime uma coluna de todos os caracteres de uma dada string. -```tut +```scala mdoc object StringIteratorTest { def main(args: Array[String]) { class Iter extends StringIterator("Scala") with RichIterator diff --git a/_pt-br/tour/multiple-parameter-lists.md b/_pt-br/tour/multiple-parameter-lists.md index 4db4692e7f..8523bc75ba 100644 --- a/_pt-br/tour/multiple-parameter-lists.md +++ b/_pt-br/tour/multiple-parameter-lists.md @@ -15,7 +15,7 @@ Métodos podem definir múltiplas listas de parâmetros. Quando um método é ch Aqui um exemplo: -```tut +```scala mdoc object CurryTest extends App { def filter(xs: List[Int], p: Int => Boolean): List[Int] = diff --git a/_pt-br/tour/named-arguments.md b/_pt-br/tour/named-arguments.md index 008e403cb1..0a32847873 100644 --- a/_pt-br/tour/named-arguments.md +++ b/_pt-br/tour/named-arguments.md @@ -10,7 +10,7 @@ language: pt-br Ao chamar métodos e funções, você pode utilizar explicitamente o nome das variáveis nas chamadas, por exemplo: -```tut +```scala mdoc def imprimeNome(nome:String, sobrenome:String) = { println(nome + " " + sobrenome) } @@ -22,7 +22,7 @@ imprimeNome(sobrenome = "Smith",nome = "John") // Imprime "John Smith" Perceba que a ordem não importa quando você utiliza parâmetros nomeados nas chamadas de métodos e funções, desde que todos os parâmetros sejam declarados. Essa funcionalidade pode ser combinada com [parâmetros com valor padrão](default-parameter-values.html): -```tut +```scala mdoc:nest def imprimeNome(nome:String = "John", sobrenome:String = "Smith") = { println(nome + " " + sobrenome) } diff --git a/_pt-br/tour/nested-functions.md b/_pt-br/tour/nested-functions.md index 03a446be1f..919d6f1253 100644 --- a/_pt-br/tour/nested-functions.md +++ b/_pt-br/tour/nested-functions.md @@ -11,7 +11,7 @@ language: pt-br Em scala é possível aninhar definições de funções. O objeto a seguir fornece uma função `filter` para extrair valores de uma lista de inteiros que são abaixo de um determinado valor: -```tut +```scala mdoc object FilterTest extends App { def filter(xs: List[Int], threshold: Int) = { def process(ys: List[Int]): List[Int] = diff --git a/_pt-br/tour/operators.md b/_pt-br/tour/operators.md index a84dea6dce..b38e0e3105 100644 --- a/_pt-br/tour/operators.md +++ b/_pt-br/tour/operators.md @@ -11,7 +11,7 @@ language: pt-br Qualquer método que tenha um único parâmetro pode ser usado como um *operador infix* em Scala. Aqui está a definição da classe `MyBool` que inclui os métodos `add` e `or`: -```tut +```scala mdoc case class MyBool(x: Boolean) { def and(that: MyBool): MyBool = if (x) that else this def or(that: MyBool): MyBool = if (x) this else that @@ -21,7 +21,7 @@ case class MyBool(x: Boolean) { Agora é possível utilizar as funções `and` and `or` como operadores infix: -```tut +```scala mdoc def not(x: MyBool) = x.negate def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y) ``` @@ -30,7 +30,7 @@ Isso ajuda a tornar a definição de `xor` mais legível. Aqui está o código correspondente em uma sintaxe de linguagem de programação orientada a objetos mais tradicional: -```tut +```scala mdoc:nest def not(x: MyBool) = x.negate def xor(x: MyBool, y: MyBool) = x.or(y).and(x.and(y).negate) ``` diff --git a/_pt-br/tour/pattern-matching.md b/_pt-br/tour/pattern-matching.md index 049776f0a6..1c53b3cd02 100644 --- a/_pt-br/tour/pattern-matching.md +++ b/_pt-br/tour/pattern-matching.md @@ -15,7 +15,7 @@ _Nota de tradução: A palavra cujo o significado melhor corresponde a palavra ` Scala possui mecanismo de correspondência de padrão embutido. Isso permite realizar o match de qualquer tipo de dados com a política de primeiro match. Aqui um pequeno exemplo que mostrar como realizar o match de um número inteiro: -```tut +```scala mdoc object MatchTest1 extends App { def matchTest(x: Int): String = x match { case 1 => "um" @@ -30,7 +30,7 @@ O bloco com a declaração `case` define a função que mapeia inteiros para str Aqui um segundo exemplo no qual o match é realizado em valores de diferentes tipos: -```tut +```scala mdoc object MatchTest2 extends App { def matchTest(x: Any): Any = x match { case 1 => "um" diff --git a/_pt-br/tour/polymorphic-methods.md b/_pt-br/tour/polymorphic-methods.md index a11b599a28..ed0dd535f8 100644 --- a/_pt-br/tour/polymorphic-methods.md +++ b/_pt-br/tour/polymorphic-methods.md @@ -14,7 +14,7 @@ Os métodos em Scala podem ser parametrizados com valores e tipos. Como no níve Por exemplo: -```tut +```scala mdoc def dup[T](x: T, n: Int): List[T] = { if (n == 0) Nil diff --git a/_pt-br/tour/regular-expression-patterns.md b/_pt-br/tour/regular-expression-patterns.md index 470b5bbbe3..9009118fc0 100644 --- a/_pt-br/tour/regular-expression-patterns.md +++ b/_pt-br/tour/regular-expression-patterns.md @@ -20,7 +20,7 @@ Elem(prefix:String, label:String, attrs:MetaData, scp:NamespaceBinding, children Em tais casos, Scala permite que padrões tenham o curinga `_*` na posição mais à direita para ter lugar para sequências arbitrariamente longas. O exemplo a seguir demonstra um padrão que faz o match de um prefixo de uma sequência e vincula o resto à variável `rest`. -```tut +```scala mdoc object RegExpTest1 extends App { def containsScala(x: String): Boolean = { val z: Seq[Char] = x diff --git a/_pt-br/tour/self-types.md b/_pt-br/tour/self-types.md index 764552c329..2596a83223 100644 --- a/_pt-br/tour/self-types.md +++ b/_pt-br/tour/self-types.md @@ -13,7 +13,7 @@ Ao desenvolver um software extensível, às vezes é útil declarar explicitamen Aqui está uma definição que descreve um grafo: -```tut +```scala mdoc abstract class Graph { type Edge type Node <: NodeIntf @@ -30,7 +30,7 @@ Um grafo consiste em uma lista de nós e arestas onde o nó e o tipo de aresta s Uma possível implementação de `Graph` é ilustrada na classe a seguir: -```tut:fail +```scala mdoc:fail abstract class DirectedGraph extends Graph { type Edge <: EdgeImpl class EdgeImpl(origin: Node, dest: Node) { @@ -62,7 +62,7 @@ Em Scala é possível vincular uma classe a outro tipo (que será implementado n Aqui está o programa já corrigido: -```tut +```scala mdoc abstract class DirectedGraph extends Graph { type Edge <: EdgeImpl class EdgeImpl(origin: Node, dest: Node) { @@ -93,7 +93,7 @@ Nesta nova definição de classe `NodeImpl`, `this` tem o tipo `Node`. Como o ti Aqui está uma especialização concreta de `DirectedGraph` onde todos os membros da classe abstrata são definidos: -```tut +```scala mdoc class ConcreteDirectedGraph extends DirectedGraph { type Edge = EdgeImpl type Node = NodeImpl @@ -107,7 +107,7 @@ Observe que nesta classe, podemos instanciar `NodeImpl` porque agora sabemos que Aqui está um exemplo de uso da classe `ConcreteDirectedGraph`: -```tut +```scala mdoc object GraphTest extends App { val g: Graph = new ConcreteDirectedGraph val n1 = g.addNode @@ -117,4 +117,4 @@ object GraphTest extends App { n2.connectWith(n3) n1.connectWith(n3) } -``` \ No newline at end of file +``` diff --git a/_pt-br/tour/singleton-objects.md b/_pt-br/tour/singleton-objects.md index 1f0bdc7e51..850af29abd 100644 --- a/_pt-br/tour/singleton-objects.md +++ b/_pt-br/tour/singleton-objects.md @@ -34,7 +34,7 @@ A maioria dos objetos singleton não estão sozinhos, mas sim associados com uma Se houver um objeto acompanhante para uma classe, ambos devem ser definidos no mesmo aquivo fonte. Por exemplo: -```tut +```scala mdoc class IntPair(val x: Int, val y: Int) object IntPair { diff --git a/_pt-br/tour/traits.md b/_pt-br/tour/traits.md index 261e4ac69d..23bc17e04d 100644 --- a/_pt-br/tour/traits.md +++ b/_pt-br/tour/traits.md @@ -12,7 +12,7 @@ language: pt-br Similar a interfaces em Java, traits são utilizadas para definir tipos de objetos apenas especificando as assinaturas dos métodos suportados. Como em Java 8, Scala permite que traits sejam parcialmente implementadas; ex. é possível definir uma implementação padrão para alguns métodos. Diferentemente de classes, traits não precisam ter construtores com parâmetros. Veja o exemplo a seguir: -```tut +```scala mdoc trait Similaridade { def eSemelhante(x: Any): Boolean def naoESemelhante(x: Any): Boolean = !eSemelhante(x) @@ -21,7 +21,7 @@ trait Similaridade { Tal trait consiste em dois métodos `eSemelhante` e `naoESemelhante`. Equanto `eSemelhante` não fornece um método com implementação concreta (que é semelhante ao abstract na linguagem Java), o método `naoESemelhante` define um implementação concreta. Consequentemente, classes que integram essa trait só precisam fornecer uma implementação concreta para o método `eSemelhante`. O comportamento para `naoESemelhante` é herdado diretamente da trait. Traits são tipicamente integradas a uma [classe](classes.html) (ou outras traits) utilizando a [composição mesclada de classes](mixin-class-composition.html): -```tut +```scala mdoc class Point(xc: Int, yc: Int) extends Similaridade { var x: Int = xc var y: Int = yc diff --git a/_pt-br/tour/tuples.md b/_pt-br/tour/tuples.md index f403e66b2a..4f149a48b7 100644 --- a/_pt-br/tour/tuples.md +++ b/_pt-br/tour/tuples.md @@ -15,7 +15,7 @@ Tuplas são sobretudo úteis para retornar múltiplos valores de um método. Uma Tupla com dois elementos pode ser criada dessa forma: -```tut +```scala mdoc val ingrediente = ("Açucar" , 25) ``` @@ -29,7 +29,7 @@ Para representar tuplas, Scala usa uma serie de classes: `Tuple2`, `Tuple3`, etc Uma maneira de acessar os elementos da tupla é pela sua respectiva posição. Os elementos individuais são nomeados `_1` , `_2` , e assim por diante. -```tut +```scala mdoc println(ingrediente._1) // Açucar println(ingrediente._2) // 25 ``` @@ -38,7 +38,7 @@ println(ingrediente._2) // 25 Uma tupla pode também ser desmembrada usando correspondência de padrões: -```tut +```scala mdoc val (nome, quantidade) = ingrediente println(nome) // Açucar println(quantidade) // 25 @@ -48,7 +48,7 @@ Aqui o tipo inferido para `nome` é `String` e para `quantidade` o tipo inferido Outro exemplo de correspondência de padrões em uma tupla: -```tut +```scala mdoc val planetas = List(("Mercúrio", 57.9), ("Vênus", 108.2), ("Terra", 149.6), ("Marte", 227.9), ("Júpiter", 778.3)) @@ -61,7 +61,7 @@ planetas.foreach{ Ou, um exemplo com `for` : -```tut +```scala mdoc val numPars = List((2, 5), (3, -7), (20, 56)) for ((a, b) <- numPars) { println(a * b) diff --git a/_pt-br/tour/type-inference.md b/_pt-br/tour/type-inference.md index 080eaa85ee..2a32f6d124 100644 --- a/_pt-br/tour/type-inference.md +++ b/_pt-br/tour/type-inference.md @@ -13,7 +13,7 @@ Scala tem um mecanismo nativo de inferência de tipos que permite ao programador Por exemplo: -```tut +```scala mdoc object InferenceTest1 extends App { val x = 1 + 2 * 3 // o tipo de x é Int val y = x.toString() // o tipo de y é String @@ -25,7 +25,7 @@ Para métodos recursivos, o compilador não é capaz de inferir o tipo de retorn Exemplo de um método que não irá compilar por este motivo: -```tut:fail +```scala mdoc:fail object InferenceTest2 { def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) } @@ -54,7 +54,7 @@ val y: Int = id[Int](1) Em algumas situações, pode ser muito perigoso confiar no mecanismo de inferência de tipos de Scala como mostra o seguinte programa: -```tut:fail +```scala mdoc:fail object InferenceTest4 { var obj = null obj = new Object() diff --git a/_pt-br/tour/unified-types.md b/_pt-br/tour/unified-types.md index 092ef6887f..0cb9bb86b6 100644 --- a/_pt-br/tour/unified-types.md +++ b/_pt-br/tour/unified-types.md @@ -19,7 +19,7 @@ A superclass de todas as classes `scala.Any` tem duas subclasses diretas `scala. Observe que o diagrama acima mostra implicitamente as conversões entre as classes de valores. Este exemplo demonstra que números numbers, caracteres, valores booleanos, e funções são objetos como qualquer outro objeto: -```tut +```scala object TiposUnificados extends App { val set = new scala.collection.mutable.LinkedHashSet[Any] set += "Sou uma string" // adiciona uma string ao set diff --git a/_pt-br/tour/upper-type-bounds.md b/_pt-br/tour/upper-type-bounds.md index c001028026..b90a421850 100644 --- a/_pt-br/tour/upper-type-bounds.md +++ b/_pt-br/tour/upper-type-bounds.md @@ -12,7 +12,7 @@ language: pt-br Em Scala, [parâmetros de tipos](generic-classes.html) e [tipos abstratos](abstract-type-members.html) podem ser restringidos por um limitante de tipo. Tal limitante de tipo limita os valores concretos de uma variável de tipo e possivelmente revela mais informações sobre os membros de determinados tipos. Um _limitante superiror de tipos_ `T <: A` declare que a variável tipo `T` refere-se a um subtipo do tipo `A`. Aqui um exemplo que demonstra um limitante superior de tipo para um parâmetro de tipo da classe `Cage`: -```tut +```scala mdoc abstract class Animal { def name: String } diff --git a/_pt-br/tour/variances.md b/_pt-br/tour/variances.md index 90c248aadf..5abd635810 100644 --- a/_pt-br/tour/variances.md +++ b/_pt-br/tour/variances.md @@ -13,7 +13,7 @@ Scala suporta anotações de variância de parâmetros de tipo de [classes gené Na página sobre [classes genéricas](generic-classes.html) foi dado um exemplo de uma pilha de estado mutável. Explicamos que o tipo definido pela classe `Stack [T]` está sujeito a subtipos invariantes em relação ao parâmetro de tipo. Isso pode restringir a reutilização da abstração de classe. Derivamos agora uma implementação funcional (isto é, imutável) para pilhas que não tem esta restrição. Por favor, note que este é um exemplo avançado que combina o uso de [métodos polimórficos](polymorphic-methods.html), [limites de tipo inferiores](lower-type-bounds.html) e anotações de parâmetros de tipos covariantes em um estilo não trivial. Além disso, fazemos uso de [classes internas](inner-classes.html) para encadear os elementos da pilha sem links explícitos. -```tut +```scala mdoc class Stack[+T] { def push[S >: T](elem: S): Stack[S] = new Stack[S] { override def top: S = elem diff --git a/_ru/cheatsheets/index.md b/_ru/cheatsheets/index.md index 11c1552e74..6ef64ea87a 100644 --- a/_ru/cheatsheets/index.md +++ b/_ru/cheatsheets/index.md @@ -354,4 +354,4 @@ Some(3) match { приписывание типа (во время компиляции) - \ No newline at end of file + diff --git a/_ru/overviews/collections-2.13/creating-collections-from-scratch.md b/_ru/overviews/collections-2.13/creating-collections-from-scratch.md index e705778625..1eacea990f 100644 --- a/_ru/overviews/collections-2.13/creating-collections-from-scratch.md +++ b/_ru/overviews/collections-2.13/creating-collections-from-scratch.md @@ -62,4 +62,4 @@ language: ru | `C.range(start, end)` | Коллекция из целых чисел от `start` до `end-1`. | | `C.range(start, end, step)`| Коллекция целых чисел, начиная со `start` и продвигаясь на шаг `step` увеличиваясь до конечного значения `end` (не включая его самого) . | | `C.iterate(x, n)(f)` | Коллекция длины `n` с элементами `x`, `f(x)`, `f(f(x))`, ... | -| `C.unfold(init)(f)` | Коллекция, использующая функцию `f` для вычисления следующего элемента и состояния, начиная с начального состояния `init`.| \ No newline at end of file +| `C.unfold(init)(f)` | Коллекция, использующая функцию `f` для вычисления следующего элемента и состояния, начиная с начального состояния `init`.| diff --git a/_ru/overviews/collections-2.13/equality.md b/_ru/overviews/collections-2.13/equality.md index b63d7165f7..5908d1ca2b 100644 --- a/_ru/overviews/collections-2.13/equality.md +++ b/_ru/overviews/collections-2.13/equality.md @@ -34,4 +34,4 @@ language: ru java.util.NoSuchElementException: key not found: ArrayBuffer(2, 2, 3) -В этом примере запрос в последней строке, скорее всего, не сработает, так как хэш-код массива `buf` изменился во второй с конца строке. Таким образом, в поиске элемента на основе хэша, будет запрашиваться совсем другой элемент, чем тот что был первоначально сохранен в `map`. \ No newline at end of file +В этом примере запрос в последней строке, скорее всего, не сработает, так как хэш-код массива `buf` изменился во второй с конца строке. Таким образом, в поиске элемента на основе хэша, будет запрашиваться совсем другой элемент, чем тот что был первоначально сохранен в `map`. diff --git a/_ru/overviews/collections-2.13/sets.md b/_ru/overviews/collections-2.13/sets.md index f905b07bfe..3a2bbbf98e 100644 --- a/_ru/overviews/collections-2.13/sets.md +++ b/_ru/overviews/collections-2.13/sets.md @@ -152,4 +152,4 @@ language: ru Битовые Наборы - это множество неотрицательных целочисленных элементов, которые упаковываются в пакеты. Внутреннее представление [BitSet](https://www.scala-lang.org/api/current/scala/collection/BitSet.html) использует массив `Long`ов. Первый `Long` охватывает элементы от 0 до 63, второй от 64 до 127 и так далее (Неизменяемые наборы элементов в диапазоне от 0 до 127 оптимизированны таким образом что хранят биты непосредственно в одном или двух полях типа `Long` без использования массива). Для каждого `Long` 64 бита каждого из них устанавливается значение 1, если соответствующий элемент содержится в наборе, и сбрасывается в 0 в противном случае. Отсюда следует, что размер битового набора зависит от размера самого большого числа, которое в нем хранится. Если `N` является самым большим размером числа, то размер набора будет составлять `N/64` от размера `Long`, или `N/8` байта плюс небольшое количество дополнительных байт для информации о состоянии. -Поэтому битовые наборы компактнее, чем другие множества, когда речь идет о хранении мелких элементов. Еще одним преимуществом битовых наборов является то, что такие операции, как проверка на наличие элемента `contains`, добавление либо удаление элементов с `+=` и `-=` черезвычайно эффективны. \ No newline at end of file +Поэтому битовые наборы компактнее, чем другие множества, когда речь идет о хранении мелких элементов. Еще одним преимуществом битовых наборов является то, что такие операции, как проверка на наличие элемента `contains`, добавление либо удаление элементов с `+=` и `-=` черезвычайно эффективны. diff --git a/_ru/tour/abstract-type-members.md b/_ru/tour/abstract-type-members.md index cb2a2ecc1e..849286419f 100644 --- a/_ru/tour/abstract-type-members.md +++ b/_ru/tour/abstract-type-members.md @@ -18,7 +18,7 @@ prerequisite-knowledge: variance, upper-type-bound Абстрактный означает, что только конкретный экземпляр определяет, каким именно будет тип. Вот пример: -```tut +```scala mdoc trait Buffer { type T val element: T @@ -26,7 +26,7 @@ trait Buffer { ``` Здесь мы определили абстрактный тип `T`, который используется для описания типа члена `element`. Мы можем расширить его в абстрактном классе, добавив верхнюю границу нового типа `U` связанного с `T`, делая описание типа более конкретным. -```tut +```scala mdoc abstract class SeqBuffer extends Buffer { type U type T <: Seq[U] @@ -37,7 +37,7 @@ abstract class SeqBuffer extends Buffer { [Трейты](traits.html) или [классы](classes.html) с членами абстрактного типа часто используются в сочетании с анонимными экземплярами классов. Чтобы проиллюстрировать это рассмотрим программу, которая имеет дело с буфером, который ссылается на список целых чисел: -```tut +```scala mdoc abstract class IntSeqBuffer extends SeqBuffer { type U = Int } @@ -56,7 +56,7 @@ println("content = " + buf.element) Мы можем вывести тип класса из типа его членов и наоборот. Приведем версию кода, в которой выводится тип класса из типа его члена: -```tut +```scala mdoc:nest abstract class Buffer[+T] { val element: T } @@ -74,4 +74,4 @@ println("length = " + buf.length) println("content = " + buf.element) ``` -Обратите внимание, что здесь необходимо использовать [вариантность в описании типа](variances.html) (`+T <: Seq[U]`) для того, чтобы скрыть конкретный тип реализации списка, возвращаемого из метода `newIntSeqBuf`. \ No newline at end of file +Обратите внимание, что здесь необходимо использовать [вариантность в описании типа](variances.html) (`+T <: Seq[U]`) для того, чтобы скрыть конкретный тип реализации списка, возвращаемого из метода `newIntSeqBuf`. diff --git a/_ru/tour/annotations.md b/_ru/tour/annotations.md index 23bdb8fad6..6a22a6dd27 100644 --- a/_ru/tour/annotations.md +++ b/_ru/tour/annotations.md @@ -29,7 +29,7 @@ object DeprecationDemo extends App { ## Аннотации, обеспечивающие корректность работы кода Некоторые аннотации приводят к невозможности компиляции, если условие (условия) не выполняется. Например, аннотация `@tailrec` гарантирует, что метод является [хвостовой рекурсией](https://ru.wikipedia.org/wiki/%D0%A5%D0%B2%D0%BE%D1%81%D1%82%D0%BE%D0%B2%D0%B0%D1%8F_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D1%8F). Хвостовая рекурсия помогает держать потребление памяти на постоянном уровне. Вот как она используется в методе, который вычисляет факториал: -```tut +```scala mdoc import scala.annotation.tailrec def factorial(x: Int): Int = { diff --git a/_ru/tour/basics.md b/_ru/tour/basics.md index 6fab580323..f6c3788f4c 100644 --- a/_ru/tour/basics.md +++ b/_ru/tour/basics.md @@ -31,13 +31,13 @@ previous-page: tour-of-scala ## Выражения Выражения — это вычислимые утверждения. -``` +```scala mdoc 1 + 1 ``` Вы можете выводить результаты выражений, используя `println`. {% scalafiddle %} -```tut +```scala mdoc println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! @@ -49,7 +49,7 @@ println("Hello," + " world!") // Hello, world! Результаты выражений можно присваивать именам с помощью ключевого слова `val`. -```tut +```scala mdoc val x = 1 + 1 println(x) // 2 ``` @@ -59,13 +59,13 @@ println(x) // 2 Значения не изменяемы и не могут быть переназначены. -```tut:fail +```scala mdoc:fail x = 3 // Не компилируется. ``` Типы значений могут быть выведены автоматически, но можно и явно указать тип, как показано ниже: -```tut +```scala mdoc:nest val x: Int = 1 + 1 ``` @@ -75,7 +75,7 @@ val x: Int = 1 + 1 Переменные похожи на значения константы, за исключением того, что их можно присваивать заново. Вы можете объявить переменную с помощью ключевого слова `var`. -```tut +```scala mdoc:nest var x = 1 + 1 x = 3 // Компилируется потому что "x" объявлен с ключевым словом "var". println(x * x) // 9 @@ -83,7 +83,7 @@ println(x * x) // 9 Как и в случае со значениями, вы можете явно указать тип, если захотите: -```tut +```scala mdoc:nest var x: Int = 1 + 1 ``` @@ -94,7 +94,7 @@ var x: Int = 1 + 1 Результат последнего выражения в блоке будет результатом всего блока в целом. -```tut +```scala mdoc println({ val x = 1 + 1 x + 1 @@ -107,7 +107,7 @@ println({ Вы можете определить анонимную функцию (т.е. без имени), которая возвращает переданное число, прибавив к нему единицу: -```tut +```scala mdoc (x: Int) => x + 1 ``` @@ -116,7 +116,7 @@ println({ Вы также можете назвать функции. {% scalafiddle %} -```tut +```scala mdoc val addOne = (x: Int) => x + 1 println(addOne(1)) // 2 ``` @@ -125,7 +125,7 @@ println(addOne(1)) // 2 Функции могут принимать множество параметров. {% scalafiddle %} -```tut +```scala mdoc val add = (x: Int, y: Int) => x + y println(add(1, 2)) // 3 ``` @@ -133,7 +133,7 @@ println(add(1, 2)) // 3 Или вообще не принимать никаких параметров. -```tut +```scala mdoc val getTheAnswer = () => 42 println(getTheAnswer()) // 42 ``` @@ -145,7 +145,7 @@ println(getTheAnswer()) // 42 Методы задаются ключевым словом `def`. За `def` следует имя, список параметров, возвращаемый тип и тело. {% scalafiddle %} -```tut +```scala mdoc:nest def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3 ``` @@ -156,7 +156,7 @@ println(add(1, 2)) // 3 Методы могут принимать несколько списков параметров. {% scalafiddle %} -```tut +```scala mdoc def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9 ``` @@ -164,7 +164,7 @@ println(addThenMultiply(1, 2)(3)) // 9 Или вообще ни одного списка параметров. -```tut +```scala mdoc def name: String = System.getProperty("user.name") println("Hello, " + name + "!") ``` @@ -174,7 +174,7 @@ println("Hello, " + name + "!") Методы также могут иметь многострочные выражения. {% scalafiddle %} -```tut +```scala mdoc def getSquareString(input: Double): String = { val square = input * input square.toString @@ -189,7 +189,7 @@ println(getSquareString(2.5)) // 6.25 Вы можете объявлять классы используя ключевое слово `class`, за которым следует его имя и параметры конструктора. -```tut +```scala mdoc class Greeter(prefix: String, suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) @@ -199,7 +199,7 @@ class Greeter(prefix: String, suffix: String) { Вы можете создать экземпляр класса, используя ключевое слово `new`. -```tut +```scala mdoc val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` @@ -210,13 +210,13 @@ greeter.greet("Scala developer") // Hello, Scala developer! В Scala есть специальный тип класса, который называется классом-образцом (case class). По умолчанию такие классы неизменны и сравниваются по значению из конструктора. Вы можете объявлять классы-образцы с помощью ключевых слов `case class`. -```tut +```scala mdoc case class Point(x: Int, y: Int) ``` Можно создавать экземпляры класса-образца без использования ключевого слова `new`. -```tut +```scala mdoc val point = Point(1, 2) val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2) @@ -224,7 +224,7 @@ val yetAnotherPoint = Point(2, 2) Они сравниваются по значению. -```tut +```scala mdoc if (point == anotherPoint) { println(point + " and " + anotherPoint + " are the same.") } else { @@ -246,7 +246,7 @@ if (point == yetAnotherPoint) { Вы можете задать объекты при помощи ключевого слова `object`. -```tut +```scala mdoc object IdFactory { private var counter = 0 def create(): Int = { @@ -258,7 +258,7 @@ object IdFactory { Вы можете сразу получить доступ к объекту, ссылаясь на его имя. -```tut +```scala mdoc val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() @@ -273,7 +273,7 @@ println(newerId) // 2 Объявить трейт можно с помощью ключевого слова `trait`. -```tut +```scala mdoc:nest trait Greeter { def greet(name: String): Unit } @@ -282,7 +282,7 @@ trait Greeter { Трейты также могут иметь реализации методов и полей, которые предполагается использовать умолчанию. {% scalafiddle %} -```tut +```scala mdoc:reset trait Greeter { def greet(name: String): Unit = println("Hello, " + name + "!") @@ -291,7 +291,7 @@ trait Greeter { Вы можете наследовать свойства трейтов, используя ключевое слово `extends` и переопределять реализацию с помощью ключевого слова `override`. -```tut +```scala mdoc class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { @@ -319,7 +319,7 @@ customGreeter.greet("Scala developer") // How are you, Scala developer? Используя объект, можно задать главный метод следующим образом: -```tut +```scala mdoc object Main { def main(args: Array[String]): Unit = println("Hello, Scala developer!") diff --git a/_ru/tour/by-name-parameters.md b/_ru/tour/by-name-parameters.md index 9cd798b2ee..4a1a4d4417 100644 --- a/_ru/tour/by-name-parameters.md +++ b/_ru/tour/by-name-parameters.md @@ -14,14 +14,14 @@ previous-page: operators --- _Вызов параметров по имени_ - это когда значение параметра вычисляется только в момент вызова параметра. Этот способ противоположен _вызову по значению_. Чтоб вызов параметра был по имени, необходимо просто указать `=>` перед его типом. -```tut +```scala mdoc def calculate(input: => Int) = input * 37 ``` Преимущество вызова параметров по имени заключается в том, что они не вычисляются если не используются в теле функции. С другой стороны плюсы вызова параметров по значению в том, что они вычисляются только один раз. Вот пример того, как мы можем реализовать условный цикл: -```tut +```scala mdoc def whileLoop(condition: => Boolean)(body: => Unit): Unit = if (condition) { body diff --git a/_ru/tour/case-classes.md b/_ru/tour/case-classes.md index 13c3622587..7891df767a 100644 --- a/_ru/tour/case-classes.md +++ b/_ru/tour/case-classes.md @@ -18,7 +18,7 @@ prerequisite-knowledge: classes, basics, mutability ## Объявление класса образца Минимальный вариант объявления класса образца: указание ключевого слова `case class`, название и список параметров (которые могут быть пустыми). Пример: -```tut +```scala mdoc case class Book(isbn: String) val frankenstein = Book("978-0486282114") diff --git a/_ru/tour/classes.md b/_ru/tour/classes.md index 0b5a7e0bec..db66150841 100644 --- a/_ru/tour/classes.md +++ b/_ru/tour/classes.md @@ -19,14 +19,14 @@ prerequisite-knowledge: no-return-keyword, type-declaration-syntax, string-inter ## Объявление класса Минимальное объявление класса - это просто ключевое слово `class` и его имя. Имена классов должны быть написаны с заглавной буквы. -```tut +```scala mdoc class User val user1 = new User ``` Ключевое слово `new` используется для создания экземпляра класса. `User` имеет конструктор по умолчанию, который не принимает аргументов, так как конструктор не был определен. Однако обычно используется и конструктор, и тело класса. Пример объявления класса Point приведен ниже: -```tut +```scala mdoc class Point(var x: Int, var y: Int) { def move(dx: Int, dy: Int): Unit = { @@ -50,7 +50,7 @@ println(point1) // prints (2, 3) Конструкторы могут иметь необязательные параметры, если указать их значения по умолчанию как в примере: -```tut +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val origin = new Point // x и y оба равны 0 @@ -60,7 +60,7 @@ println(point1.x) // выводит 1 ``` В этой версии класса `Point`, `x` и `y` имеют значение по умолчанию `0`, поэтому аргументов не требуется. Однако, поскольку конструктор считывает аргументы слева направо, если вы просто хотите передать значение `y`, то вам нужно будет указать задаваемый параметр. -``` +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val point2 = new Point(y=2) println(point2.y) // выводит 2 @@ -70,7 +70,7 @@ println(point2.y) // выводит 2 ## Скрытые члены и синтаксис Геттер/Сеттер (получатель/установщик значений) По умолчанию члены класса являются открытыми для внешнего доступа (публичными). Используйте модификатор `private`, чтобы скрыть их от внешнего доступа. -```tut +```scala mdoc:nest class Point { private var _x = 0 private var _y = 0 @@ -96,14 +96,14 @@ point1.y = 101 // выводит предупреждение (printWarning) В данной версии класса `Point` данные хранятся в скрытых переменных `_x` и `_y`. Существуют методы `def x` и `def y` для доступа к скрытым данным. Методы `def x_=` и `def y_=` (сеттеры) предназначены для проверки и установки значения `_x` и `_y`. Обратите внимание на специальный синтаксис для сеттеров: метод `_=` применяется к имени геттера. Первичные параметры конструктора с параметрами `val` и `var` являются общедоступными. Однако, поскольку `val` - это константа, то нельзя писать следующее. -``` +```scala mdoc:fail class Point(val x: Int, val y: Int) val point = new Point(1, 2) point.x = 3 // <-- не компилируется ``` Параметры без `val` или `var` являются скрытыми от внешнего доступа и видимы только внутри класса. -``` +```scala mdoc:fail class Point(x: Int, y: Int) val point = new Point(1, 2) point.x // <-- не компилируется diff --git a/_ru/tour/compound-types.md b/_ru/tour/compound-types.md index 988900cab4..eb861afbfd 100644 --- a/_ru/tour/compound-types.md +++ b/_ru/tour/compound-types.md @@ -17,7 +17,7 @@ previous-page: abstract-type-members Предположим, у нас есть два трейта: `Cloneable` и `Resetable`: -```tut +```scala mdoc trait Cloneable extends java.lang.Cloneable { override def clone(): Cloneable = { super.clone().asInstanceOf[Cloneable] diff --git a/_ru/tour/default-parameter-values.md b/_ru/tour/default-parameter-values.md index 0286d62e18..72ab55e786 100644 --- a/_ru/tour/default-parameter-values.md +++ b/_ru/tour/default-parameter-values.md @@ -16,7 +16,7 @@ prerequisite-knowledge: named-arguments, function syntax Scala предоставляет возможность задавать значения параметров по умолчанию, что позволяет лишний раз не указывать параметры. -```tut +```scala mdoc def log(message: String, level: String = "INFO") = println(s"$level: $message") log("System starting") // выведет "INFO: System starting" @@ -25,7 +25,7 @@ log("User not found", "WARNING") // выведет "WARNING: User not found" У параметра `level` есть значение по умолчанию, поэтому он необязателен. В последней строке аргумент `"WARNING"` переназначает аргумент по умолчанию `"INFO"`. Вместо того чтоб использовать перегруженные методы в Java, вы можете просто указать дополнительные параметры как параметры по умолчанию для достижения того же эффекта. Однако, если при вызове пропущен хотя бы один аргумент, все остальные аргументы должны вызываться с указанием конкретного имени аргумента. -```tut +```scala mdoc class Point(val x: Double = 0, val y: Double = 0) val point1 = new Point(y = 1) @@ -34,7 +34,7 @@ val point1 = new Point(y = 1) Обратите внимание, что параметры по умолчанию в Scala, при вызове из Java кода, являются обязательными: -```tut +```scala mdoc:reset // Point.scala class Point(val x: Double = 0, val y: Double = 0) ``` diff --git a/_ru/tour/extractor-objects.md b/_ru/tour/extractor-objects.md index d3824e69c3..0c968f36cd 100644 --- a/_ru/tour/extractor-objects.md +++ b/_ru/tour/extractor-objects.md @@ -15,7 +15,7 @@ previous-page: regular-expression-patterns Объект Экстрактор (объект распаковщик или extractor object) - это объект с методом `unapply`. В то время как метод `apply` обычно действует как конструктор, который принимает аргументы и создает объект, метод `unapply` действует обратным образом, он принимает объект и пытается извлечь и вернуть аргументы из которых он (возможно) был создан. Чаще всего этот метод используется в функциях сопоставления с примером и в частично определенных функциях. -```tut +```scala mdoc import scala.util.Random object CustomerID { @@ -38,7 +38,7 @@ customer1ID match { При объявлении нового значения можно использовать пример, в котором значение для инициализации переменной получается через извлечение, используя метод `unapply`. -```tut +```scala mdoc val customer2ID = CustomerID("Nico") val CustomerID(name) = customer2ID println(name) // выведет Nico @@ -46,13 +46,13 @@ println(name) // выведет Nico Что эквивалентно `val name = CustomerID.unapply(customer2ID).get`. -```tut +```scala mdoc val CustomerID(name2) = "--asdfasdfasdf" ``` Если совпадений нет, то бросается `scala.MatchError`: -```tut:fail +```scala mdoc:crash val CustomerID(name3) = "-asdfasdfasdf" ``` diff --git a/_ru/tour/for-comprehensions.md b/_ru/tour/for-comprehensions.md index 5c79ca062c..2e824afb1d 100644 --- a/_ru/tour/for-comprehensions.md +++ b/_ru/tour/for-comprehensions.md @@ -17,7 +17,7 @@ Scala предлагает простую запись для выражения Вот пример: -```tut +```scala mdoc case class User(name: String, age: Int) val userBase = List(User("Travis", 28), @@ -34,7 +34,7 @@ twentySomethings.foreach(name => println(name)) // выводит "Travis Denni Ниже приведен более сложный пример использования двух генераторов. Он вычисляет все пары чисел между `0` и `n-1`, сумма которых равна заданному значению `v`: -```tut +```scala mdoc def foo(n: Int, v: Int) = for (i <- 0 until n; j <- i until n if i + j == v) @@ -47,7 +47,7 @@ foo(10, 10) foreach { ``` Здесь `n == 10` и `v == 10`. На первой итерации `i == 0` и `j == 0` так `i + j != v` и поэтому ничего не выдается. `j` увеличивается еще в 9 раз, прежде чем `i` увеличивается до `1`. Без фильтра `if` будет просто напечатано следующее: -``` +```scala (0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) (0, 9) (1, 1) ... ``` @@ -56,7 +56,7 @@ foo(10, 10) foreach { Вы можете обойтись без `yield` в for-выражении. В таком случае, результатом будет `Unit`. Это может быть полезным для выполнения кода основанного на побочных эффектах. Вот программа, эквивалентная предыдущей, но без использования `yield`: -```tut +```scala mdoc:nest def foo(n: Int, v: Int) = for (i <- 0 until n; j <- i until n if i + j == v) diff --git a/_ru/tour/generic-classes.md b/_ru/tour/generic-classes.md index 30587567ca..2087f753cb 100644 --- a/_ru/tour/generic-classes.md +++ b/_ru/tour/generic-classes.md @@ -17,7 +17,7 @@ assumed-knowledge: classes unified-types ## Объявление обобщенного класса Для объявления обобщенного класса необходимо после имени добавить тип в квадратных скобках `[]` как еще один параметр класса. По соглашению обычно используют заглавные буквы `A`, хотя можно использовать любые имена. -```tut +```scala mdoc class Stack[A] { private var elements: List[A] = Nil def push(x: A) { elements = x :: elements } diff --git a/_ru/tour/higher-order-functions.md b/_ru/tour/higher-order-functions.md index 6df55532e9..0b4416ed4b 100644 --- a/_ru/tour/higher-order-functions.md +++ b/_ru/tour/higher-order-functions.md @@ -19,7 +19,7 @@ previous-page: mixin-class-composition Одним из наиболее распространенных примеров функции высшего порядка является функция `map`, которая доступна в коллекциях Scala. -```tut +```scala mdoc val salaries = Seq(20000, 70000, 40000) val doubleSalary = (x: Int) => x * 2 val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000) @@ -27,13 +27,13 @@ val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000) `doubleSalary` - это функция, которая принимает один Int `x` и возвращает `x * 2`. В общем случае, кортеж (список имен в скобках) слева от стрелки `=>` - это список параметров, а значение выражения следует справа. Это же значение возвращается в качестве результата. В строке 3 к каждому элементу списка зарплат (salaries) применяется функция `doubleSalary`. Чтобы сократить код, мы можем сделать функцию анонимной и передать ее напрямую в качестве аргумента в map: -``` +```scala mdoc:nest val salaries = Seq(20000, 70000, 40000) val newSalaries = salaries.map(x => x * 2) // List(40000, 140000, 80000) ``` Обратите внимание, что в приведенном выше примере `x`не объявлен как `Int`. Это потому, что компилятор может вывести тип, основываясь на типе который ожидает функция map. Еще более элегантным способом написания этого же кода было бы таким: -```tut +```scala mdoc:nest val salaries = Seq(20000, 70000, 40000) val newSalaries = salaries.map(_ * 2) ``` @@ -41,7 +41,7 @@ val newSalaries = salaries.map(_ * 2) ## Преобразование методов в функции Также возможно передавать методы в качестве аргументов функциям более высокого порядка, поскольку компилятор Scala может преобразовать метод в функцию. -``` +```scala mdoc case class WeeklyWeatherForecast(temperatures: Seq[Double]) { private def convertCtoF(temp: Double) = temp * 1.8 + 32 @@ -54,7 +54,7 @@ case class WeeklyWeatherForecast(temperatures: Seq[Double]) { ## Функции, которые принимают функции Одной из причин использования функций высшего порядка является сокращение избыточного кода. Допустим, вам нужны какие-то методы, которые могли бы повышать чью-то зарплату по разным условиям. Без создания функции высшего порядка это могло бы выглядеть примерно так: -```tut +```scala mdoc object SalaryRaiser { def smallPromotion(salaries: List[Double]): List[Double] = @@ -70,7 +70,7 @@ object SalaryRaiser { Обратите внимание, что каждый из этих трех методов отличается только коэффициентом умножения. Для упрощения можно перенести повторяющийся код в функцию высшего порядка: -```tut +```scala mdoc:nest object SalaryRaiser { private def promotion(salaries: List[Double], promotionFunction: Double => Double): List[Double] = @@ -93,7 +93,7 @@ object SalaryRaiser { Есть определенные случаи, когда вы хотите сгенерировать функцию. Вот пример метода, который возвращает функцию. -```tut +```scala mdoc def urlBuilder(ssl: Boolean, domainName: String): (String, String) => String = { val schema = if (ssl) "https://" else "http://" (endpoint: String, query: String) => s"$schema$domainName/$endpoint?$query" @@ -106,4 +106,4 @@ val query = "id=1" val url = getURL(endpoint, query) // "https://www.example.com/users?id=1": String ``` -Обратите внимание, что возвращаемый тип urlBuilder`(String, String) => String`. Это означает, что возвращаемая анонимная функция принимает две строки и возвращает строку. В нашем случае возвращаемая анонимная функция `(endpoint: String, query: String) => s"https://www.example.com/$endpoint?$query"`. \ No newline at end of file +Обратите внимание, что возвращаемый тип urlBuilder`(String, String) => String`. Это означает, что возвращаемая анонимная функция принимает две строки и возвращает строку. В нашем случае возвращаемая анонимная функция `(endpoint: String, query: String) => s"https://www.example.com/$endpoint?$query"`. diff --git a/_ru/tour/implicit-conversions.md b/_ru/tour/implicit-conversions.md index 1040f47f9b..bd36a9e749 100644 --- a/_ru/tour/implicit-conversions.md +++ b/_ru/tour/implicit-conversions.md @@ -31,7 +31,7 @@ List(1, 2, 3) <= List(4, 5) Неявный метод `Int => Ordered[Int]` предоставляется автоматически через `scala.Predef.intWrapper`. Ниже приведен пример объявления неявного метода `List[A] => Ordered[List[A]]`. -```tut +```scala mdoc import scala.language.implicitConversions implicit def list2ordered[A](x: List[A]) @@ -46,7 +46,7 @@ implicit def list2ordered[A](x: List[A]) Например, при вызове Java метода, который ожидает `java.lang.Integer`, вместо него вы можете свободно использовать `scala.Int`. Потому что Predef включает в себя следующие неявные преобразования: -```tut +```scala mdoc import scala.language.implicitConversions implicit def int2Integer(x: Int) = diff --git a/_ru/tour/implicit-parameters.md b/_ru/tour/implicit-parameters.md index e9f7756e15..cf58ded10e 100644 --- a/_ru/tour/implicit-parameters.md +++ b/_ru/tour/implicit-parameters.md @@ -24,7 +24,7 @@ previous-page: self-types В следующем примере мы определяем метод `sum`, который вычисляет сумму элементов списка, используя операции `add` и `unit` моноида. Обратите внимание, что неявные значения не могут находится выше уровнем. -```tut +```scala mdoc abstract class Monoid[A] { def add(x: A, y: A): A def unit: A diff --git a/_ru/tour/inner-classes.md b/_ru/tour/inner-classes.md index d56cdcdd32..736677ceff 100644 --- a/_ru/tour/inner-classes.md +++ b/_ru/tour/inner-classes.md @@ -17,7 +17,7 @@ previous-page: lower-type-bounds Чтобы проиллюстрировать суть подхода, мы быстро набросаем реализацию такого графа: -```tut +```scala mdoc class Graph { class Node { var connectedNodes: List[Node] = Nil @@ -37,7 +37,7 @@ class Graph { ``` Данная программа представляет собой граф в составленного из списка узлов (`List[Node]`). Каждый узел имеет список других узлов, с которым он связан (`connectedNodes`). Класс `Node` является _зависимым от месторасположения типом_, поскольку он вложен в `Class Graph`. Поэтому все узлы в `connectedNodes` должны быть созданы с использованием `newNode` из одного и того же экземпляра `Graph`. -```tut +```scala mdoc val graph1: Graph = new Graph val node1: graph1.Node = graph1.newNode val node2: graph1.Node = graph1.newNode @@ -50,7 +50,7 @@ node3.connectTo(node1) Если у нас есть два графа, то система типов Scala не позволит смешивать узлы, определенные в рамках одного графа, с узлами другого, так как узлы другого графа имеют другой тип. Вот некорректная программа: -``` +```scala:nest val graph1: Graph = new Graph val node1: graph1.Node = graph1.newNode val node2: graph1.Node = graph1.newNode @@ -61,7 +61,7 @@ node1.connectTo(node3) // не работает! ``` Тип `graph1.Node` отличается от типа `graph2.Node`. В Java последняя строка в предыдущем примере программы была бы правильной. Для узлов обоих графов Java будет присваивать один и тот же тип `Graph.Node`, т.е. `Node` имеет префикс класса `Graph`. В Скале такой тип также может быть выражен, он записывается `Graph#Node`. Если мы хотим иметь возможность соединять узлы разных графов, то вам нужно изменить описание первоначальной реализации графов следующим образом: -```tut +```scala mdoc:nest class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil diff --git a/_ru/tour/lower-type-bounds.md b/_ru/tour/lower-type-bounds.md index 27000cc863..8351695a72 100644 --- a/_ru/tour/lower-type-bounds.md +++ b/_ru/tour/lower-type-bounds.md @@ -18,7 +18,7 @@ prerequisite-knowledge: upper-type-bounds, generics, variance Вот пример, где это полезно: -```tut:fail +```scala mdoc:fail trait Node[+B] { def prepend(elem: B): Node[B] } @@ -40,7 +40,7 @@ case class Nil[+B]() extends Node[B] { Чтобы исправить это, необходимо перевернуть вариантность типа параметра `elem` в `prepend`. Для этого мы вводим новый тип для параметра `U`, у которого тип `B` указан в качестве нижней границы типа. -```tut +```scala mdoc trait Node[+B] { def prepend[U >: B](elem: U): Node[U] } @@ -57,7 +57,7 @@ case class Nil[+B]() extends Node[B] { ``` Теперь мы можем сделать следующее: -```tut +```scala mdoc trait Bird case class AfricanSwallow() extends Bird case class EuropeanSwallow() extends Bird diff --git a/_ru/tour/mixin-class-composition.md b/_ru/tour/mixin-class-composition.md index 4c528ca3c9..ff7c1d60d9 100644 --- a/_ru/tour/mixin-class-composition.md +++ b/_ru/tour/mixin-class-composition.md @@ -15,7 +15,7 @@ prerequisite-knowledge: inheritance, traits, abstract-classes, unified-types --- Примеси (Mixin) - это трейты, которые используются для создания класса. -```tut +```scala mdoc abstract class A { val message: String } @@ -35,7 +35,7 @@ println(d.loudMessage) // I'M AN INSTANCE OF CLASS B Теперь давайте рассмотрим более интересный пример, начиная с абстрактного класса: -```tut +```scala mdoc abstract class AbsIterator { type T def hasNext: Boolean @@ -46,7 +46,7 @@ abstract class AbsIterator { Далее создаем конкретную реализацию класса (все абстрактные члены `T`, `hasNext`, и `next` должны быть реализованы): -```tut +```scala mdoc class StringIterator(s: String) extends AbsIterator { type T = Char private var i = 0 @@ -62,7 +62,7 @@ class StringIterator(s: String) extends AbsIterator { Теперь давайте создадим трейт который тоже наследуется от `AbsIterator`. -```tut +```scala mdoc trait RichIterator extends AbsIterator { def foreach(f: T => Unit): Unit = while (hasNext) f(next()) } @@ -71,7 +71,7 @@ trait RichIterator extends AbsIterator { Мы бы хотели объединить функциональность `StringIterator` и `RichIterator` в один класс. -```tut +```scala mdoc object StringIteratorTest extends App { class RichStringIter extends StringIterator("Scala") with RichIterator val richStringIter = new RichStringIter diff --git a/_ru/tour/multiple-parameter-lists.md b/_ru/tour/multiple-parameter-lists.md index 6b5e5008df..74896ca6c5 100644 --- a/_ru/tour/multiple-parameter-lists.md +++ b/_ru/tour/multiple-parameter-lists.md @@ -17,20 +17,20 @@ previous-page: nested-functions Например, - ```tut - val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - val numberFunc = numbers.foldLeft(List[Int]()) _ - - val squares = numberFunc((xs, x) => xs :+ x*x) - print(squares) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) - - val cubes = numberFunc((xs, x) => xs :+ x*x*x) - print(cubes) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000) - ``` +```scala mdoc +val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) +val numberFunc = numbers.foldLeft(List[Int]()) _ -Рассмотрим такие примеры из класса [Traversable](/overviews/collections/trait-traversable.html) коллекции Scala: +val squares = numberFunc((xs, x) => xs :+ x*x) +print(squares) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) +val cubes = numberFunc((xs, x) => xs :+ x*x*x) +print(cubes) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000) ``` + +Рассмотрим такие примеры из класса [Traversable](/overviews/collections/trait-traversable.html) коллекции Scala: + +```scala mdoc:fail def foldLeft[B](z: B)(op: (B, A) => B): B ``` @@ -38,7 +38,7 @@ def foldLeft[B](z: B)(op: (B, A) => B): B Начиная с начального значения 0, `foldLeft` применяет функцию `(m, n) => m + n` к каждому элементу списка и предыдущему накопленному значению. -```tut +```scala mdoc:nest val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val res = numbers.foldLeft(0)((m, n) => m + n) print(res) // 55 @@ -48,17 +48,17 @@ print(res) // 55 #### Отдельный функциональный параметр Функцию `op` можно выделить в отдельный функциональный параметр у `foldLeft`, благодаря такому выделению становится возможен более элегантный стиль передачи анонимной функции в метод. Без такого выделения код выглядел бы следующим образом: -``` +```scala numbers.foldLeft(0, {(m: Int, n: Int) => m + n}) ``` Обратите внимание, что использование отдельного функционального параметра позволяет нам использовать автоматическое выведение типа для него, что делает код еще более кратким, это было бы невозможно без каррирования. -``` +```scala mdoc numbers.foldLeft(0)(_ + _) ``` Если в утверждении `numbers.foldLeft(0)(_ + _)` зафиксировать отдельный параметр `z`, мы получим частично определенную функцию, которую можно переиспользовать, как показано ниже: -```tut +```scala mdoc:nest val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val numberFunc = numbers.foldLeft(List[Int]())_ // z = Empty.List[Int] @@ -70,7 +70,7 @@ print(cubes.toString()) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000) ``` `foldLeft` и `foldRight` может быть использован в любой из следующих вариаций, -```tut +```scala mdoc:nest val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) numbers.foldLeft(0)((sum, item) => sum + item) // Общая Форма @@ -84,6 +84,6 @@ numbers.foldRight(0)(_+_) // Форма с каррированием #### Неявные параметры Чтоб указать что параметр используется неявно (`implicit`) необходимо задавать несколько списков параметров. Примером может служить следующее: -``` +```scala def execute(arg: Int)(implicit ec: ExecutionContext) = ??? ``` diff --git a/_ru/tour/named-arguments.md b/_ru/tour/named-arguments.md index defb9d4282..6ab5eafb88 100644 --- a/_ru/tour/named-arguments.md +++ b/_ru/tour/named-arguments.md @@ -16,7 +16,7 @@ prerequisite-knowledge: function-syntax При вызове методов можно конкретно указывать название задаваемого аргумента следующим образом: -```tut +```scala mdoc def printName(first: String, last: String): Unit = { println(first + " " + last) } @@ -27,7 +27,7 @@ printName(last = "Smith", first = "John") // Prints "John Smith" ``` Обратите внимание, что при указании имени параметра, порядок аргумента может быть изменен. Однако если какие-то аргументы именованного, а другие нет, то аргументы без имени должны стоять на первом месте и располагаться в том порядке, в котором описаны параметры метода. -```tut:fail +```scala mdoc:fail printName(last = "Smith", "john") // ошибка: позиция после именованного аргумента ``` diff --git a/_ru/tour/nested-functions.md b/_ru/tour/nested-functions.md index ef082c36e4..663e0fdc36 100644 --- a/_ru/tour/nested-functions.md +++ b/_ru/tour/nested-functions.md @@ -16,7 +16,7 @@ previous-page: higher-order-functions В Scala возможно объявление метода вкладывать в тело другого метода. Это реализовано в следующем примере, в котором метод `factorial` используется для вычисления факториала заданного числа: {% scalafiddle %} -```tut +```scala mdoc def factorial(x: Int): Int = { def fact(x: Int, accumulator: Int): Int = { if (x <= 1) accumulator diff --git a/_ru/tour/operators.md b/_ru/tour/operators.md index 33b4cbfd20..b80bb5b616 100644 --- a/_ru/tour/operators.md +++ b/_ru/tour/operators.md @@ -25,7 +25,7 @@ prerequisite-knowledge: case-classes ## Создание и использование операторов В качестве оператора можно использовать любой допустимый символ. Включая имена на подобии `add` или символ (символы) типа `+`. -```tut +```scala mdoc case class Vec(x: Double, y: Double) { def +(that: Vec) = Vec(this.x + that.x, this.y + that.y) } @@ -39,7 +39,7 @@ vector3.y // 3.0 ``` У класса Vec есть метод `+`, который мы использовали для добавления `vector1` и `vector2`. Используя круглые скобки, можно строить сложные выражения с читаемым синтаксисом. Пример создания класса `MyBool`, которое включает в себя методы `and` и `or` -```tut +```scala mdoc case class MyBool(x: Boolean) { def and(that: MyBool): MyBool = if (x) that else this def or(that: MyBool): MyBool = if (x) this else that @@ -49,7 +49,7 @@ case class MyBool(x: Boolean) { Теперь можно использовать операторы `and` и `or` в качестве инфиксных операторов: -```tut +```scala mdoc def not(x: MyBool) = x.negate def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y) ``` diff --git a/_ru/tour/packages-and-imports.md b/_ru/tour/packages-and-imports.md index 563871406a..2a3e6ba6ff 100644 --- a/_ru/tour/packages-and-imports.md +++ b/_ru/tour/packages-and-imports.md @@ -69,7 +69,7 @@ import users.{UserPreferences => UPrefs} // импортировать и пе Одним из отличий Scala от Java является то, что импорт можно использовать где угодно: -```tut +```scala mdoc def sqrtplus1(x: Int) = { import scala.math.sqrt sqrt(x) + 1.0 diff --git a/_ru/tour/pattern-matching.md b/_ru/tour/pattern-matching.md index a3d4dda5a4..8d329636da 100644 --- a/_ru/tour/pattern-matching.md +++ b/_ru/tour/pattern-matching.md @@ -18,7 +18,7 @@ prerequisite-knowledge: case-classes, string-interpolation, subtyping ## Синтаксис Синтаксис сопоставления с примером состоит из значения, ключевого слова `match` (сопоставить) и по крайней мере, одного пункта с примером `case`, с которым мы хотим сопоставить наше значение. -```tut +```scala mdoc import scala.util.Random val x: Int = Random.nextInt(10) @@ -33,7 +33,7 @@ x match { Значение константы `x` выше представляет собой случайное целое число от 0 до 10. `x` становится левым операндом оператора `match`, а справа - выражением с четырьмя примерами (называемые еще _вариантами_). Последний вариант `_` - позволяет "поймать все оставшиеся варианты" т. е. для любого числа больше 2. Сопоставление с примером возвращает значение. -```tut +```scala mdoc def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" @@ -48,7 +48,7 @@ matchTest(1) // one Классы образцы особенно полезны для сопоставления. -```tut +```scala mdoc abstract class Notification case class Email(sender: String, title: String, body: String) extends Notification @@ -114,7 +114,7 @@ println(showImportantNotification(importantSms, importantPeopleInfo)) ## Сопоставление только с типом Вы можете сопоставлять только по типу как в примере: -```tut +```scala mdoc abstract class Device case class Phone(model: String) extends Device { def screenOff = "Turning screen off" @@ -133,7 +133,7 @@ def goIdle(device: Device) = device match { ## Запечатанные классы Трейты и классы могут быть помечены как `sealed` это означает, что подтипы должны быть объявлены в одном файле, гарантируя тем самым, что все подтипы будут известны. -```tut +```scala mdoc sealed abstract class Furniture case class Couch() extends Furniture case class Chair() extends Furniture diff --git a/_ru/tour/polymorphic-methods.md b/_ru/tour/polymorphic-methods.md index a430aaf654..3c017b89f6 100644 --- a/_ru/tour/polymorphic-methods.md +++ b/_ru/tour/polymorphic-methods.md @@ -18,7 +18,7 @@ prerequisite-knowledge: unified-types Вот пример: -```tut +```scala mdoc def listOfDuplicates[A](x: A, length: Int): List[A] = { if (length < 1) Nil diff --git a/_ru/tour/regular-expression-patterns.md b/_ru/tour/regular-expression-patterns.md index 32877a0106..fdc775e756 100644 --- a/_ru/tour/regular-expression-patterns.md +++ b/_ru/tour/regular-expression-patterns.md @@ -15,7 +15,7 @@ previous-page: singleton-objects Регулярные выражения (Regular expression) - это специальный шаблон для поиска данных задаваемый в виде текстовой строки. Любая строка может быть преобразована в регулярное выражение методом `.r`. -```tut +```scala mdoc import scala.util.matching.Regex val numberPattern: Regex = "[0-9]".r @@ -30,7 +30,7 @@ numberPattern.findFirstMatchIn("awesomepassword") match { Используя круглые скобки можно объединять сразу несколько групп регулярных выражений. -```tut +```scala mdoc import scala.util.matching.Regex val keyValPattern: Regex = "([0-9a-zA-Z-#() ]+): ([0-9a-zA-Z-#() ]+)".r diff --git a/_ru/tour/self-types.md b/_ru/tour/self-types.md index ccc896b0ec..2ce9946450 100644 --- a/_ru/tour/self-types.md +++ b/_ru/tour/self-types.md @@ -19,7 +19,7 @@ prerequisite-knowledge: nested-classes, mixin-class-composition Самоописываемый тип - это способ сузить тип `this` или другого идентификатора, который ссылается на `this`. Синтаксис похож на синтаксис обычной функции, но означает кое-что иное. Чтобы использовать самоописываемый тип в трейте напишите: идентификатор, тип другого трейта, который хотите добавить и `=>` (например, `someIdentifier: SomeOtherTrait =>`). -```tut +```scala mdoc trait User { def username: String } diff --git a/_ru/tour/singleton-objects.md b/_ru/tour/singleton-objects.md index 2867dda492..d39f5c170e 100644 --- a/_ru/tour/singleton-objects.md +++ b/_ru/tour/singleton-objects.md @@ -19,7 +19,7 @@ prerequisite-knowledge: classes, methods, private-methods, packages, option Как член класса или как локальная переменная, он ведет себя точно так же как ленивое значение (lazy val). # Объявление одиночного объекта Объект - является значением. Объявление объекта происходит схожим с классом образом, но используется ключевое слово `object`: -```tut +```scala mdoc object Box ``` @@ -74,7 +74,7 @@ circle1.area Класс `Circle` имеет член `area`, который специфичен для каждого конкретного экземпляра, а метод `calculateArea` одиночного объекта `Circle`, доступен для каждого экземпляра класса `Circle`. Объект компаньон может также содержать методы создающие конкретные экземпляры класса спутника: -```tut +```scala mdoc class Email(val username: String, val domainName: String) object Email { diff --git a/_ru/tour/tour-of-scala.md b/_ru/tour/tour-of-scala.md index 637a12d8cc..ac523d9914 100644 --- a/_ru/tour/tour-of-scala.md +++ b/_ru/tour/tour-of-scala.md @@ -61,4 +61,4 @@ Scala полностью совместим с популярной средой ## Наслаждайтесь туром! -Для продолжения знакомства предлагаю перейти на [следующую страницу](basics.html) нашего тура. \ No newline at end of file +Для продолжения знакомства предлагаю перейти на [следующую страницу](basics.html) нашего тура. diff --git a/_ru/tour/traits.md b/_ru/tour/traits.md index 468e2b7f60..bbd1e05b41 100644 --- a/_ru/tour/traits.md +++ b/_ru/tour/traits.md @@ -20,12 +20,12 @@ prerequisite-knowledge: expressions, classes, generics, objects, companion-objec ## Объявление трейта Минимальное объявление трейта - это просто ключевое слово `trait` и его имя: -```tut +```scala mdoc trait HairColor ``` Трейты наиболее полезны в качестве обобщенного типа с абстрактными методами. -```tut +```scala mdoc trait Iterator[A] { def hasNext: Boolean def next(): A @@ -36,7 +36,7 @@ trait Iterator[A] { ## Использование трейтов Чтоб использовать трейты, необходимо наследовать класс от него используя ключевое слово `extends`. Затем необходимо реализовать все абстрактные члены трейта, используя ключевое слово `override`: -```tut +```scala mdoc:nest trait Iterator[A] { def hasNext: Boolean def next(): A @@ -63,7 +63,7 @@ iterator.next() // вернет 1 ## Подтипы Туда где требуется определенный тип трейта, мы можем передавать любой наследованный от требуемого трейта класс -```tut +```scala mdoc import scala.collection.mutable.ArrayBuffer trait Pet { diff --git a/_ru/tour/tuples.md b/_ru/tour/tuples.md index 094a76fbdf..8d30c607c5 100644 --- a/_ru/tour/tuples.md +++ b/_ru/tour/tuples.md @@ -21,7 +21,7 @@ topics: tuples Кортеж может быть создан как: -```tut +```scala mdoc val ingredient = ("Sugar" , 25):Tuple2[String, Int] ``` Такая запись создает кортеж размерности 2, содержащий пару элементов String и Int. @@ -36,7 +36,7 @@ val ingredient = ("Sugar" , 25):Tuple2[String, Int] Доступ к элементам кортежа осуществляется при помощи синтаксиса подчеркивания. 'tuple._n' дает n-ый элемент (столько, сколько существует элементов). -```tut +```scala mdoc println(ingredient._1) // Sugar println(ingredient._2) // 25 @@ -46,7 +46,7 @@ println(ingredient._2) // 25 Scala кортежи также поддерживают [распаковку](extractor-objects.html). -```tut +```scala mdoc val (name, quantity) = ingredient println(name) // Sugar @@ -56,7 +56,7 @@ println(quantity) // 25 Распаковка данных кортежа может быть использована в [сопоставлении с примером](pattern-matching.html) -```tut +```scala mdoc val planetDistanceFromSun = List(("Mercury", 57.9), ("Venus", 108.2), ("Earth", 149.6 ), ("Mars", 227.9), ("Jupiter", 778.3)) planetDistanceFromSun.foreach{ tuple => { @@ -80,7 +80,7 @@ planetDistanceFromSun.foreach{ tuple => { Или в ['for' выражении](for-comprehensions.html). -```tut +```scala mdoc val numPairs = List((2, 5), (3, -7), (20, 56)) for ((a, b) <- numPairs) { diff --git a/_ru/tour/type-inference.md b/_ru/tour/type-inference.md index 45aa9c1754..5e5e39cf17 100644 --- a/_ru/tour/type-inference.md +++ b/_ru/tour/type-inference.md @@ -16,19 +16,19 @@ previous-page: polymorphic-methods ## Не указывая тип -```tut +```scala mdoc val businessName = "Montreux Jazz Café" ``` Компилятор может определить, что тип константы `businessName` является `String`. Аналогичным образом это работает и для методов: -```tut +```scala mdoc def squareOf(x: Int) = x * x ``` Компилятор может определить, что возвращаемый тип является `Int`, поэтому явного указания типа не требуется. Для рекурсивных методов компилятор не в состоянии вывести тип. Вот программа, которая не скомпилируется по этой причине: -```tut:fail +```scala mdoc:fail def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) ``` @@ -36,7 +36,7 @@ def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) Вот два примера: -```tut +```scala mdoc case class MyPair[A, B](x: A, y: B) val p = MyPair(1, "scala") // тип: MyPair[Int, String] @@ -50,7 +50,7 @@ val q = id(1) // тип: Int Для параметров компилятор никогда не выводит тип. Однако, в некоторых случаях, он может вывести типы для параметров анонимной функции при передаче ее в качестве аргумента. -```tut +```scala mdoc Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) ``` @@ -62,14 +62,14 @@ Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) Кроме того, выведение может иногда приводить к слишком специфичному типу. Предположим, мы напишем: -```tut +```scala var obj = null ``` Тогда мы не сможем далее сделать это переназначение: -```tut:fail +```scala mdoc:fail obj = new AnyRef ``` -Такое не будет компилироваться, потому что для `obj` предполагался тип `Null`. Поскольку единственным значением этого типа является `null`, то невозможно присвоить другое значение. \ No newline at end of file +Такое не будет компилироваться, потому что для `obj` предполагался тип `Null`. Поскольку единственным значением этого типа является `null`, то невозможно присвоить другое значение. diff --git a/_ru/tour/unified-types.md b/_ru/tour/unified-types.md index 2f9c9f08f4..1bd87556b7 100644 --- a/_ru/tour/unified-types.md +++ b/_ru/tour/unified-types.md @@ -28,7 +28,7 @@ prerequisite-knowledge: classes, basics Вот пример, демонстрирующий, что строки, целые числа, символы, логические значения и функции являются объектами, как и любой другой объект: -```tut +```scala mdoc val list: List[Any] = List( "a string", 732, // целое число @@ -58,7 +58,7 @@ true Например: -```tut +```scala mdoc val x: Long = 987654321 val y: Float = x // 9.8765434E8 (заметьте, что некоторая точность теряется в этом случае.) diff --git a/_ru/tour/upper-type-bounds.md b/_ru/tour/upper-type-bounds.md index 7446261c1a..60ca550d59 100644 --- a/_ru/tour/upper-type-bounds.md +++ b/_ru/tour/upper-type-bounds.md @@ -16,7 +16,7 @@ previous-page: variances В Scala [параметры типа](generic-classes.html) и [члены абстрактного типа](abstract-type-members.html) могут быть ограничены определенными диапазонами. Такие диапазоны ограничивают конкретные значение типа и, возможно, предоставляют больше информации о членах таких типов. _Верхнее ограничение типа_ `T <: A` указывает на то что тип `T` относится к подтипу типа `A`. Приведем пример, демонстрирующий верхнее ограничение для типа класса `PetContainer`: -```tut +```scala mdoc abstract class Animal { def name: String } @@ -43,7 +43,7 @@ val dogContainer = new PetContainer[Dog](new Dog) val catContainer = new PetContainer[Cat](new Cat) ``` -```tut:fail +```scala mdoc:fail // это не скомпилируется val lionContainer = new PetContainer[Lion](new Lion) ``` diff --git a/_ru/tour/variances.md b/_ru/tour/variances.md index 96e597c635..c59549f340 100644 --- a/_ru/tour/variances.md +++ b/_ru/tour/variances.md @@ -15,7 +15,7 @@ previous-page: generic-classes Вариантность (Variances) - это указание определенной специфики взаимосвязи между связанными типам. Scala поддерживает вариантную аннотацию типов у [обобщенных классов](generic-classes.html), что позволяет им быть ковариантными, контрвариантными или инвариантными (если нет никакого указание на вариантность). Использование вариантности в системе типов позволяет устанавливать понятные взаимосвязи между сложными типами, в то время как отсутствие вариантности может ограничить повторное использование абстракции класса. -```tut +```scala mdoc class Foo[+A] // ковариантный класс class Bar[-A] // контрвариантный класс class Baz[A] // инвариантными класс @@ -27,7 +27,7 @@ class Baz[A] // инвариантными класс Рассмотрим простую структуру классов: -```tut +```scala mdoc abstract class Animal { def name: String } @@ -39,7 +39,7 @@ case class Dog(name: String) extends Animal В следующем примере метод `printAnimalNames` принимает в качестве аргумента список животных и выводит их имена в новой строке. Если бы `List[A]` не был ковариантным, последние два вызова метода не компилировались бы, что сильно ограничило бы полезность метода `printAnimalNames`. -```tut +```scala mdoc object CovarianceTest extends App { def printAnimalNames(animals: List[Animal]): Unit = { animals.foreach { animal => @@ -66,7 +66,7 @@ object CovarianceTest extends App { Рассмотрим классы `Cat`, `Dog`, и `Animal`, описанные выше для следующего примера: -```tut +```scala mdoc abstract class Printer[-A] { def print(value: A): Unit } @@ -74,7 +74,7 @@ abstract class Printer[-A] { `Printer[A]` - это простой класс, который знает, как распечатать некоторый тип `A`. Давайте определим подклассы для конкретных типов: -```tut +```scala mdoc class AnimalPrinter extends Printer[Animal] { def print(animal: Animal): Unit = println("The animal's name is: " + animal.name) @@ -88,7 +88,7 @@ class CatPrinter extends Printer[Cat] { Если `Printer[Cat]` знает, как распечатать любой класс `Cat` в консоли, а `Printer[Animal]` знает, как распечатать любое `Animal` в консоли, то разумно если `Printer[Animal]` также знает, как распечатать любое `Cat`. Обратного отношения нет, потому что `Printer[Cat]` не знает, как распечатать любой `Animal` в консоли. Чтоб иметь возможность заменить `Printer[Cat]` на `Printer[Animal]`, необходимо `Printer[A]` сделать контрвариантным. -```tut +```scala mdoc object ContravarianceTest extends App { val myCat: Cat = Cat("Boots") @@ -115,7 +115,7 @@ The animal's name is: Boots Обобщенные классы в Scala по умолчанию являются инвариантными. Это означает, что они не являются ни ковариантными, ни контрвариантными друг другу. В контексте следующего примера класс `Container` является инвариантным. Между `Container[Cat]` и `Container[Animal]`, нет ни прямой, ни обратной взаимосвязи. -```tut +```scala mdoc class Container[A](value: A) { private var _value: A = value def getValue: A = _value @@ -142,7 +142,7 @@ val cat: Cat = catContainer.getValue // Ой, мы бы закончили пр Рассмотрим схожий пример `Cat`, `Dog`, `Animal` в той же взаимосвязи что и раньше, плюс следующее: -```tut +```scala mdoc abstract class SmallAnimal extends Animal case class Mouse(name: String) extends SmallAnimal ``` diff --git a/_sips/sips/2018-07-31-interpolation-quote-escape.md b/_sips/sips/2018-07-31-interpolation-quote-escape.md index 2ddfa682e6..fe6615f12f 100644 --- a/_sips/sips/2018-07-31-interpolation-quote-escape.md +++ b/_sips/sips/2018-07-31-interpolation-quote-escape.md @@ -126,4 +126,4 @@ proposals. [^4]: https://github.com/scala/bug/issues/6476#issuecomment-292412577 "@retronym said: +1 to s"$"". Because it doesn't compile today, we don't risk changing the meaning of existing programs." [^5]: https://github.com/Scala/Scala/pull/6953/files#diff-0023b3bfa053fb16603156b785efa7ad "" [^6]: https://github.com/Scala/Scala/pull/4308 "SI-6476 Accept escaped quotes in interp strings" -[^7]: https://github.com/lampepfl/dotty/pull/7486 "PR in dotty" \ No newline at end of file +[^7]: https://github.com/lampepfl/dotty/pull/7486 "PR in dotty" diff --git a/_sips/sips/2018-08-20-converters-among-optional-functions-partialfunctions-and-extractor-objects.md b/_sips/sips/2018-08-20-converters-among-optional-functions-partialfunctions-and-extractor-objects.md index 9448fbcfc9..7bd7571ea8 100644 --- a/_sips/sips/2018-08-20-converters-among-optional-functions-partialfunctions-and-extractor-objects.md +++ b/_sips/sips/2018-08-20-converters-among-optional-functions-partialfunctions-and-extractor-objects.md @@ -146,4 +146,4 @@ The new implementation aims to become part of core library. The pull request can 2. [Related Pull Request][2] [1]: https://github.com/ThoughtWorksInc/Extractor.scala "Extractor.scala" -[2]: https://github.com/scala/scala/pull/7111 "#7111" \ No newline at end of file +[2]: https://github.com/scala/scala/pull/7111 "#7111" diff --git a/_th/tour/basics.md b/_th/tour/basics.md index 19f9874285..48c285511e 100644 --- a/_th/tour/basics.md +++ b/_th/tour/basics.md @@ -28,13 +28,13 @@ In this page, we will cover basics of Scala. ## Expressions Expression หรือ นิพจน์ เป็นโค้ดที่ทำการคำนวนได้ -``` +```scala mdoc 1 + 1 ``` เราสามารถแสดงผลลัพธ์ของ Expression ด้วยการใช้ `println` {% scalafiddle %} -```tut +```scala mdoc println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! @@ -46,7 +46,7 @@ println("Hello," + " world!") // Hello, world! เราสามารถตั้งชื่อของผลลัพธ์ของ expression ด้วย keyword `val` -```tut +```scala mdoc val x = 1 + 1 println(x) // 2 ``` @@ -55,13 +55,13 @@ println(x) // 2 Value ไม่สามารถกำหนดค่าใหม่ได้ -```tut:fail +```scala mdoc:fail x = 3 // ตรงนี้ไม่ compile. ``` type (ชนิด) ของ value สามารถ inferred (อนุมาน) ได้ แต่เราสามารถกำหนดชนิดของ type อย่างชัดเจนได้ แบบนี้ -```tut +```scala mdoc:nest val x: Int = 1 + 1 ``` @@ -71,7 +71,7 @@ val x: Int = 1 + 1 ตัวแปรเหมือนกับ value ยกเว้นแต่ว่าเราสามารถกำหนดค่าใหม่ได้ เราสามารถกำหนดตัวแปรด้วย keyword `var` -```tut +```scala mdoc:nest var x = 1 + 1 x = 3 // ตรงนี้ compile เพราะว่า "x" ถูกประกาศด้วย keyword "var" println(x * x) // 9 @@ -79,7 +79,7 @@ println(x * x) // 9 เราสามารถกำหนด type ได้ตามที่เราต้องการ: -```tut +```scala mdoc:nest var x: Int = 1 + 1 ``` @@ -90,7 +90,7 @@ var x: Int = 1 + 1 ผลลัพธ์ของ expression สุดท้ายใน block จะเป็นผลลัพธ์ของ block ทั้งหมดด้วย -```tut +```scala mdoc println({ val x = 1 + 1 x + 1 @@ -103,7 +103,7 @@ function เป็น expression ที่รับ parameter ได้ เราสามารถกำหนด anonymous function (เป็น function ที่ไม่มีชื่อ) ที่ return ค่าตัวเลขบวกหนึ่ง: -```tut +```scala mdoc (x: Int) => x + 1 ``` @@ -112,7 +112,7 @@ function เป็น expression ที่รับ parameter ได้ เราสามารถตั้งชื่อของ function ได้ดังนี้ {% scalafiddle %} -```tut +```scala mdoc val addOne = (x: Int) => x + 1 println(addOne(1)) // 2 ``` @@ -121,7 +121,7 @@ println(addOne(1)) // 2 function สามารถรับ parameter ได้หลายตัว {% scalafiddle %} -```tut +```scala mdoc val add = (x: Int, y: Int) => x + y println(add(1, 2)) // 3 ``` @@ -129,7 +129,7 @@ println(add(1, 2)) // 3 หรือ เราจะไม่รับ parameter เลยก็ได้ -```tut +```scala mdoc val getTheAnswer = () => 42 println(getTheAnswer()) // 42 ``` @@ -141,7 +141,7 @@ Method มีลักษณะเหมือนกับ function มาก Method จะประกาศได้ด้วย keyword `def` ตามด้วยชื่อของ function, รายการ parameter, return type และ body ของ function {% scalafiddle %} -```tut +```scala mdoc:nest def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3 ``` @@ -152,7 +152,7 @@ println(add(1, 2)) // 3 Method ยังสามารถรับรายการ parameter ได้หลายรายการ {% scalafiddle %} -```tut +```scala mdoc def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9 ``` @@ -160,7 +160,7 @@ println(addThenMultiply(1, 2)(3)) // 9 หรือ ไม่มีรายการ parameter เลยก็ได้ อย่างเช่น -```tut +```scala mdoc def name: String = System.getProperty("user.name") println("Hello, " + name + "!") ``` @@ -170,7 +170,7 @@ println("Hello, " + name + "!") Method สามารถมี expression ได้หลายบรรทัด {% scalafiddle %} -```tut +```scala mdoc def getSquareString(input: Double): String = { val square = input * input square.toString @@ -185,7 +185,7 @@ expression สุดท้ายใน body เป็น expression ที่ re เราสามารถประกาศ class ได้ด้วย keyword `class` ตามด้วยชื่อของ class และ constructor parameters -```tut +```scala mdoc class Greeter(prefix: String, suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) @@ -195,7 +195,7 @@ return type ของ method `greet` เป็น `Unit` ซึ่งอาจ เราสามารถสร้าง instance ของ class ได้ด้วย keyword `new` -```tut +```scala mdoc val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` @@ -206,13 +206,13 @@ greeter.greet("Scala developer") // Hello, Scala developer! Scala มี type ชนิดพิเศษของ class เรียกว่า "case" class โดยเริ่มต้นแล้ว case class เป็นค่าที่เปลี่ยนแปลงไม่ได้ (immutable) และสามารถเปลียบเทียบด้วย value เราสามารถประกาศ case class ด้วย keyword `case class` -```tut +```scala mdoc case class Point(x: Int, y: Int) ``` เราสามารถสร้าง instant ของ case class โดยไม่ต้องใช้ keyword `new` -```tut +```scala mdoc val point = Point(1, 2) val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2) @@ -220,7 +220,7 @@ val yetAnotherPoint = Point(2, 2) และสามารถเปรียบเทียบค่าของ case class ได้ -```tut +```scala mdoc if (point == anotherPoint) { println(point + " and " + anotherPoint + " are the same.") } else { @@ -242,7 +242,7 @@ Object เป็น instance เดี่ยวของ definition ของม เราสามารถประกาศ object ได้ด้วย keyword `object` -```tut +```scala mdoc object IdFactory { private var counter = 0 def create(): Int = { @@ -254,7 +254,7 @@ object IdFactory { เราสามารถเข้าถึง object ด้วยการอ้างอิงถึงชื่อของมัน -```tut +```scala mdoc val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() @@ -269,7 +269,7 @@ Trait เป็น type ที่บรรจุ field และ method ที เราสามารถประกาศ trait ได้ด้วย keyword `trait` -```tut +```scala mdoc:nest trait Greeter { def greet(name: String): Unit } @@ -278,7 +278,7 @@ trait Greeter { Trait สามารถมี default implementation ได้ {% scalafiddle %} -```tut +```scala mdoc:reset trait Greeter { def greet(name: String): Unit = println("Hello, " + name + "!") @@ -287,7 +287,7 @@ trait Greeter { เราสามารถขยาย traint ได้ด้วย keyword `extents` และ overrid implementation ด้วย keyword `override` -```tut +```scala mdoc class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { @@ -315,7 +315,7 @@ main method เป็น entry point หรือจุดเริ่มต้ ใช้ object เราสามารถประกาศ main method ได้ดังนี้: -```tut +```scala mdoc object Main { def main(args: Array[String]): Unit = println("Hello, Scala developer!") diff --git a/_th/tour/classes.md b/_th/tour/classes.md index 43f0ccef93..7800a5f492 100644 --- a/_th/tour/classes.md +++ b/_th/tour/classes.md @@ -17,7 +17,7 @@ trait และคลาส ซึ่งเรียกรวมๆ กันว ## การกำหนดคลาส วิธีการที่ง่ายที่สุดในการกำหนดคลาสด้วยการใช้ keyword `class` และ identifier ชื่อของคลาสควรจะขึ้นต้นด้วยตัวพิมพ์ใหญ่ -```tut +```scala mdoc class User val user1 = new User @@ -27,7 +27,7 @@ keyword `new` ใช้เพื่อสร้าง instance ของคล อย่างไรก็ตาม, เราอาจจะมี constructor และ body ของคลาส ตัวอย่างดังนี้ เป็นการประกาศคลาสสำหรับจุด (point): -```tut +```scala mdoc class Point(var x: Int, var y: Int) { def move(dx: Int, dy: Int): Unit = { @@ -53,7 +53,7 @@ method `move` รับ argument ชนิดตัวเลข 2 ตัว แ ​Constructor สามารถมี parameter ตัวเลือกได้ โดยกำหนดค่าเริ่มต้นดังนี้: -```tut +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val origin = new Point // x and y are both set to 0 @@ -65,7 +65,7 @@ println(point1.x) // พิมพ์ 1 ในคลาส `Point` ดังกล่าว `x` และ `y` มีค่าเริ่มต้นเป็น `0` ดังนั้นเราสามาถไม่ใส่ argument ก็ได้ อย่างไรก็ตาม เพราะว่า constructor อ่าน argument จากซ้ายไปขวา ถ้าเราต้องการใส่ค่าใน `y` ไปในคลาส เราจำเป็นต้องระบุชื่อของ parameter ด้วย -``` +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val point2 = new Point(y=2) println(point2.y) // พิมพ์ 2 @@ -76,7 +76,7 @@ println(point2.y) // พิมพ์ 2 ## Private Members และ Getter/Setter สมาชิกของคลาสจะเป็น public โดยค่าเริ่มต้น ใช้ access modifier `private` เพื่อซ่อนสมาชิกนั้นจากภายนอกของคลาส -```tut +```scala mdoc:reset class Point { private var _x = 0 private var _y = 0 @@ -104,14 +104,14 @@ point1.y = 101 // พิมพ์คำเตือน warning สังเกตว่า syntax พิเศษนี้สำหรับ setter: คือ method ที่ตามด้วย `_=` ไปยังตัวระบุของ setter และ parameter ตามหลังมา constructor หลักกำหนด parameter ด้วย `val` และ `var` เป็น public อย่างไรก็ตามเพราะว่า `val` เป็นตัวแปรที่เปลี่ยนแปลงไม่ได้ (immutable) เราไม่สามารถเขียบแบบนี้ได้ -``` +```scala mdoc:fail class Point(val x: Int, val y: Int) val point = new Point(1, 2) point.x = 3 // <-- ตรงนี้ไม่ compile ``` parameter ที่ไม่มี `val` หรือ `var` เป็นค่า private จะมองเห็นได้เพียงข้างในคลาส -``` +```scala mdoc:fail class Point(x: Int, y: Int) val point = new Point(1, 2) point.x // <-- ตรงนี้ไม่ compile diff --git a/_th/tour/traits.md b/_th/tour/traits.md index 0c1a62315f..dfc3b31a74 100644 --- a/_th/tour/traits.md +++ b/_th/tour/traits.md @@ -17,11 +17,11 @@ Trait ใช้เพื่อแชร์ interface และ field ระห ## การกำหนด trait วิธีที่ง่ายที่สุดในการกำหนด trait คือการประกาศด้วย keyword `trait` และ indentifier: -```tut +```scala mdoc trait HairColor ``` trait จะมีประโยชน์อย่างยิ่งด้วยการเป็น generic type และเป็น abstract method -```tut +```scala mdoc trait Iterator[A] { def hasNext: Boolean def next(): A @@ -32,7 +32,7 @@ trait Iterator[A] { ## การใช้ traits ใช้ keyword `extends` เพื่อขยาย trait ดังนั้นจะ implement abstract member ใดๆ ของ trait โดยใช้ keyword `override`: -```tut +```scala mdoc:nest trait Iterator[A] { def hasNext: Boolean def next(): A @@ -59,7 +59,7 @@ iterator.next() // returns 1 ## Subtyping ในเมื่อ trait ที่ให้มานั้น required, subtype ของ trait สามารถถูกใช้แทนที่ได้ -```tut +```scala mdoc import scala.collection.mutable.ArrayBuffer trait Pet { @@ -78,4 +78,4 @@ animals.append(cat) animals.foreach(pet => println(pet.name)) // พิมพ์ Harry Sally ``` `trait Pet` มี abstract field `name` ซึ่ง implement โดย Cat และ Dog ใน constructor ของมัน -ในบรรทัดสุดท้าย เราเรียก `pet.name` ซึ่งจะต้องถูก implement แล้วใน subtype ใดๆ ของ trait `Pet` \ No newline at end of file +ในบรรทัดสุดท้าย เราเรียก `pet.name` ซึ่งจะต้องถูก implement แล้วใน subtype ใดๆ ของ trait `Pet` diff --git a/_th/tour/tuples.md b/_th/tour/tuples.md index e35ae7b968..16ae8432df 100644 --- a/_th/tour/tuples.md +++ b/_th/tour/tuples.md @@ -12,4 +12,4 @@ previous-page: traits --- (this section of the tour has not been translated yet. pull request -with translation welcome!) \ No newline at end of file +with translation welcome!) diff --git a/_th/tour/unified-types.md b/_th/tour/unified-types.md index 2ab810f145..7e92c8a39f 100644 --- a/_th/tour/unified-types.md +++ b/_th/tour/unified-types.md @@ -25,7 +25,7 @@ previous-page: basics นี่เป็นตัวอย่างที่แสดงให้เห็นการใช้งาน string, integer, charecter, boolean value และ function เป็น object ทั้งหมดที่เหมือนกับ obejct อื่น: -```tut +```scala mdoc val list: List[Any] = List( "a string", 732, // an integer @@ -55,7 +55,7 @@ Value type สามารถแปลได้ด้วยวิธีดัง ตัวอย่างเช่น: -```tut +```scala mdoc val x: Long = 987654321 val y: Float = x // 9.8765434E8 (หมายเหตุว่าค่าความละเอียดจะสูญหายไปในกรณีนี้) @@ -76,4 +76,4 @@ val z: Long = y // ไม่เป็นไปตามที่ต้องก ## Nothing และ Null `Nothing` เป็น subtype ของ value type ทั้งหมด และยังเรียกว่าเป็น type ล่างสุด ค่าที่ไม่มีค่าจะเป็น type `Nothing` ส่วนมากจะใช้ในกรณี single non-termination อย่างเช่น throw exception, program exit หรือ infinite loop (นั้นคือ มันเป็น type ของ expression ที่ไม่มีการประเมินค่าของ value หรือ method ที่ไม่มีการ return ค่าในแบบปรกติ) -`Null` เป็น subtype ของ reference type ทั้งหมด (นั้นคือ เป็น subtype ของ AnyRef) มันมีการระบุ value เดียวด้วย keyword `null` ซึ่ง `Null` ใช้ส่วนใหญ่สำหรับการทำงานร่วมกันกับภาษา JVM และไม่ควรใช้ในโค้ดของ Scala เราจะครอบคลุมวิธีการอื่นแทน `null` ในภายหลัง \ No newline at end of file +`Null` เป็น subtype ของ reference type ทั้งหมด (นั้นคือ เป็น subtype ของ AnyRef) มันมีการระบุ value เดียวด้วย keyword `null` ซึ่ง `Null` ใช้ส่วนใหญ่สำหรับการทำงานร่วมกันกับภาษา JVM และไม่ควรใช้ในโค้ดของ Scala เราจะครอบคลุมวิธีการอื่นแทน `null` ในภายหลัง diff --git a/_tour/abstract-type-members.md b/_tour/abstract-type-members.md index f3704aa048..8cad19b617 100644 --- a/_tour/abstract-type-members.md +++ b/_tour/abstract-type-members.md @@ -16,7 +16,7 @@ Abstract types, such as traits and abstract classes, can in turn have abstract t This means that the concrete implementations define the actual types. Here's an example: -```tut +```scala mdoc trait Buffer { type T val element: T @@ -24,7 +24,7 @@ trait Buffer { ``` Here we have defined an abstract `type T`. It is used to describe the type of `element`. We can extend this trait in an abstract class, adding an upper-type-bound to `T` to make it more specific. -```tut +```scala mdoc abstract class SeqBuffer extends Buffer { type U type T <: Seq[U] @@ -35,7 +35,7 @@ Notice how we can use yet another abstract type `U` in the specification of an u Traits or [classes](classes.html) with abstract type members are often used in combination with anonymous class instantiations. To illustrate this, we now look at a program which deals with a sequence buffer that refers to a list of integers: -```tut +```scala mdoc abstract class IntSeqBuffer extends SeqBuffer { type U = Int } @@ -54,7 +54,7 @@ Here the factory `newIntSeqBuf` uses an anonymous class implementation of `IntSe It is also possible to turn abstract type members into type parameters of classes and vice versa. Here is a version of the code above which only uses type parameters: -```tut +```scala mdoc:nest abstract class Buffer[+T] { val element: T } diff --git a/_tour/annotations.md b/_tour/annotations.md index d424dd0155..bdd39a09b7 100644 --- a/_tour/annotations.md +++ b/_tour/annotations.md @@ -26,7 +26,7 @@ An annotation clause applies to the first definition or declaration following it ## Annotations that ensure correctness of encodings Certain annotations will actually cause compilation to fail if a condition(s) is not met. For example, the annotation `@tailrec` ensures that a method is [tail-recursive](https://en.wikipedia.org/wiki/Tail_call). Tail-recursion can keep memory requirements constant. Here's how it's used in a method which calculates the factorial: -```tut +```scala mdoc import scala.annotation.tailrec def factorial(x: Int): Int = { diff --git a/_tour/basics.md b/_tour/basics.md index 48b72d54c1..f5acd95ab3 100644 --- a/_tour/basics.md +++ b/_tour/basics.md @@ -25,13 +25,13 @@ _ScalaFiddle_ is integrated with some of the code examples in this documentation ## Expressions Expressions are computable statements: -``` +```scala mdoc 1 + 1 ``` You can output the results of expressions using `println`: {% scalafiddle %} -```tut +```scala mdoc println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! @@ -43,7 +43,7 @@ println("Hello," + " world!") // Hello, world! You can name the results of expressions using the `val` keyword: -```tut +```scala mdoc val x = 1 + 1 println(x) // 2 ``` @@ -53,13 +53,13 @@ a value does not re-compute it. Values cannot be re-assigned: -```tut:fail +```scala mdoc:fail x = 3 // This does not compile. ``` The type of a value can be omitted and [inferred](https://docs.scala-lang.org/tour/type-inference.html), or it can be explicitly stated: -```tut +```scala mdoc:nest val x: Int = 1 + 1 ``` @@ -69,7 +69,7 @@ Notice how the type declaration `Int` comes after the identifier `x`. You also n Variables are like values, except you can re-assign them. You can define a variable with the `var` keyword. -```tut +```scala mdoc:nest var x = 1 + 1 x = 3 // This compiles because "x" is declared with the "var" keyword. println(x * x) // 9 @@ -77,7 +77,7 @@ println(x * x) // 9 As with values, the type of a variable can be omitted and [inferred](https://docs.scala-lang.org/tour/type-inference.html), or it can be explicitly stated: -```tut +```scala mdoc:nest var x: Int = 1 + 1 ``` @@ -88,7 +88,7 @@ You can combine expressions by surrounding them with `{}`. We call this a block. The result of the last expression in the block is the result of the overall block, too: -```tut +```scala mdoc println({ val x = 1 + 1 x + 1 @@ -101,7 +101,7 @@ Functions are expressions that have parameters, and take arguments. You can define an anonymous function (i.e., a function that has no name) that returns a given integer plus one: -```tut +```scala mdoc (x: Int) => x + 1 ``` @@ -110,7 +110,7 @@ On the left of `=>` is a list of parameters. On the right is an expression invol You can also name functions: {% scalafiddle %} -```tut +```scala mdoc val addOne = (x: Int) => x + 1 println(addOne(1)) // 2 ``` @@ -119,7 +119,7 @@ println(addOne(1)) // 2 A function can have multiple parameters: {% scalafiddle %} -```tut +```scala mdoc val add = (x: Int, y: Int) => x + y println(add(1, 2)) // 3 ``` @@ -127,7 +127,7 @@ println(add(1, 2)) // 3 Or it can have no parameters at all: -```tut +```scala mdoc val getTheAnswer = () => 42 println(getTheAnswer()) // 42 ``` @@ -139,7 +139,7 @@ Methods look and behave very similar to functions, but there are a few key diffe Methods are defined with the `def` keyword. `def` is followed by a name, parameter list(s), a return type, and a body: {% scalafiddle %} -```tut +```scala mdoc:nest def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3 ``` @@ -150,7 +150,7 @@ Notice how the return type `Int` is declared _after_ the parameter list and a `: A method can take multiple parameter lists: {% scalafiddle %} -```tut +```scala mdoc def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9 ``` @@ -158,7 +158,7 @@ println(addThenMultiply(1, 2)(3)) // 9 Or no parameter lists at all: -```tut +```scala mdoc def name: String = System.getProperty("user.name") println("Hello, " + name + "!") ``` @@ -168,7 +168,7 @@ There are some other differences, but for now, you can think of methods as somet Methods can have multi-line expressions as well: {% scalafiddle %} -```tut +```scala mdoc def getSquareString(input: Double): String = { val square = input * input square.toString @@ -183,7 +183,7 @@ The last expression in the body is the method's return value. (Scala does have a You can define classes with the `class` keyword, followed by its name and constructor parameters: -```tut +```scala mdoc class Greeter(prefix: String, suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) @@ -193,7 +193,7 @@ The return type of the method `greet` is `Unit`, which signifies that there is n You can make an instance of a class with the `new` keyword: -```tut +```scala mdoc:nest val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` @@ -206,13 +206,13 @@ Scala has a special type of class called a "case" class. By default, instances o You can define case classes with the `case class` keywords: -```tut +```scala mdoc case class Point(x: Int, y: Int) ``` You can instantiate case classes without the `new` keyword: -```tut +```scala mdoc val point = Point(1, 2) val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2) @@ -220,7 +220,7 @@ val yetAnotherPoint = Point(2, 2) Instances of case classes are compared by value, not by reference: -```tut +```scala mdoc if (point == anotherPoint) { println(point + " and " + anotherPoint + " are the same.") } else { @@ -242,7 +242,7 @@ Objects are single instances of their own definitions. You can think of them as You can define objects with the `object` keyword: -```tut +```scala mdoc object IdFactory { private var counter = 0 def create(): Int = { @@ -254,7 +254,7 @@ object IdFactory { You can access an object by referring to its name: -```tut +```scala mdoc val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() @@ -269,7 +269,7 @@ Traits are abstract data types containing certain fields and methods. In Scala i You can define traits with the `trait` keyword: -```tut +```scala mdoc:nest trait Greeter { def greet(name: String): Unit } @@ -278,7 +278,7 @@ trait Greeter { Traits can also have default implementations: {% scalafiddle %} -```tut +```scala mdoc:reset trait Greeter { def greet(name: String): Unit = println("Hello, " + name + "!") @@ -287,7 +287,7 @@ trait Greeter { You can extend traits with the `extends` keyword and override an implementation with the `override` keyword: -```tut +```scala mdoc class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { @@ -316,7 +316,7 @@ argument: an array of strings. Using an object, you can define the main method as follows: -```tut +```scala mdoc object Main { def main(args: Array[String]): Unit = println("Hello, Scala developer!") diff --git a/_tour/by-name-parameters.md b/_tour/by-name-parameters.md index cf4fd9c6af..6d0ff8b610 100644 --- a/_tour/by-name-parameters.md +++ b/_tour/by-name-parameters.md @@ -11,14 +11,14 @@ redirect_from: "/tutorials/tour/by-name-parameters.html" --- _By-name parameters_ are evaluated every time they are used. They won't be evaluated at all if they are unused. This is similar to replacing the by-name parameters with the passed expressions. They are in contrast to _by-value parameters_. To make a parameter called by-name, simply prepend `=>` to its type. -```tut +```scala mdoc def calculate(input: => Int) = input * 37 ``` By-name parameters have the advantage that they are not evaluated if they aren't used in the function body. On the other hand, by-value parameters have the advantage that they are evaluated only once. Here's an example of how we could implement a while loop: -```tut +```scala mdoc def whileLoop(condition: => Boolean)(body: => Unit): Unit = if (condition) { body diff --git a/_tour/case-classes.md b/_tour/case-classes.md index f07d1f2f92..b05756f81b 100644 --- a/_tour/case-classes.md +++ b/_tour/case-classes.md @@ -15,7 +15,7 @@ Case classes are like regular classes with a few key differences which we will g ## Defining a case class A minimal case class requires the keywords `case class`, an identifier, and a parameter list (which may be empty): -```tut +```scala mdoc case class Book(isbn: String) val frankenstein = Book("978-0486282114") @@ -34,7 +34,7 @@ You can't reassign `message1.sender` because it is a `val` (i.e. immutable). It ## Comparison Instances of case classes are compared by structure and not by reference: -```tut +```scala mdoc case class Message(sender: String, recipient: String, body: String) val message2 = Message("jorge@catalonia.es", "guillaume@quebec.ca", "Com va?") @@ -45,7 +45,7 @@ Even though `message2` and `message3` refer to different objects, the value of e ## Copying 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. -```tut +```scala mdoc:nest case class Message(sender: String, recipient: String, body: String) val message4 = Message("julien@bretagne.fr", "travis@washington.us", "Me zo o komz gant ma amezeg") val message5 = message4.copy(sender = message4.recipient, recipient = "claire@bourgogne.fr") diff --git a/_tour/classes.md b/_tour/classes.md index c713d0adc4..47b5079bc5 100644 --- a/_tour/classes.md +++ b/_tour/classes.md @@ -18,14 +18,14 @@ values, variables, types, objects, traits, and classes which are collectively ca ## Defining a class A minimal class definition is simply the keyword `class` and an identifier. Class names should be capitalized. -```tut +```scala mdoc class User val user1 = new User ``` The keyword `new` is used to create an instance of the class. `User` has a default constructor which takes no arguments because no constructor was defined. However, you'll often want a constructor and class body. Here is an example class definition for a point: -```tut +```scala mdoc class Point(var x: Int, var y: Int) { def move(dx: Int, dy: Int): Unit = { @@ -49,7 +49,7 @@ This `Point` class has four members: the variables `x` and `y` and the methods ` Constructors can have optional parameters by providing a default value like so: -```tut +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val origin = new Point // x and y are both set to 0 @@ -59,7 +59,7 @@ println(point1.x) // prints 1 ``` In this version of the `Point` class, `x` and `y` have the default value `0` so no arguments are required. However, because the constructor reads arguments left to right, if you just wanted to pass in a `y` value, you would need to name the parameter. -``` +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val point2 = new Point(y = 2) println(point2.y) // prints 2 @@ -70,7 +70,7 @@ This is also a good practice to enhance clarity. ## Private Members and Getter/Setter Syntax Members are public by default. Use the `private` access modifier to hide them from outside of the class. -```tut +```scala mdoc:reset class Point { private var _x = 0 private var _y = 0 @@ -96,14 +96,14 @@ point1.y = 101 // prints the warning In this version of the `Point` class, the data is stored in private variables `_x` and `_y`. There are methods `def x` and `def y` for accessing the private data. `def x_=` and `def y_=` are for validating and setting the value of `_x` and `_y`. Notice the special syntax for the setters: the method has `_=` appended to the identifier of the getter and the parameters come after. Primary constructor parameters with `val` and `var` are public. However, because `val`s are immutable, you can't write the following. -``` +```scala mdoc:fail class Point(val x: Int, val y: Int) val point = new Point(1, 2) point.x = 3 // <-- does not compile ``` Parameters without `val` or `var` are private values, visible only within the class. -``` +```scala mdoc:fail class Point(x: Int, y: Int) val point = new Point(1, 2) point.x // <-- does not compile diff --git a/_tour/compound-types.md b/_tour/compound-types.md index 6bb6cf9009..4cd53674b5 100644 --- a/_tour/compound-types.md +++ b/_tour/compound-types.md @@ -14,7 +14,7 @@ Sometimes it is necessary to express that the type of an object is a subtype of Suppose we have two traits `Cloneable` and `Resetable`: -```tut +```scala mdoc trait Cloneable extends java.lang.Cloneable { override def clone(): Cloneable = { super.clone().asInstanceOf[Cloneable] diff --git a/_tour/default-parameter-values.md b/_tour/default-parameter-values.md index e0fc4da17b..60776fd228 100644 --- a/_tour/default-parameter-values.md +++ b/_tour/default-parameter-values.md @@ -13,7 +13,7 @@ redirect_from: "/tutorials/tour/default-parameter-values.html" Scala provides the ability to give parameters default values that can be used to allow a caller to omit those parameters. -```tut +```scala mdoc def log(message: String, level: String = "INFO") = println(s"$level: $message") log("System starting") // prints INFO: System starting @@ -22,7 +22,7 @@ log("User not found", "WARNING") // prints WARNING: User not found The parameter `level` has a default value so it is optional. On the last line, the argument `"WARNING"` overrides the default argument `"INFO"`. Where you might do overloaded methods in Java, you can use methods with optional parameters to achieve the same effect. However, if the caller omits an argument, any following arguments must be named. -```tut +```scala mdoc class Point(val x: Double = 0, val y: Double = 0) val point1 = new Point(y = 1) @@ -31,7 +31,7 @@ Here we have to say `y = 1`. Note that default parameters in Scala are not optional when called from Java code: -```tut +```scala mdoc:reset // Point.scala class Point(val x: Double = 0, val y: Double = 0) ``` diff --git a/_tour/extractor-objects.md b/_tour/extractor-objects.md index 5441efe6e0..b7e08ed708 100644 --- a/_tour/extractor-objects.md +++ b/_tour/extractor-objects.md @@ -12,7 +12,7 @@ redirect_from: "/tutorials/tour/extractor-objects.html" An extractor object is an object with an `unapply` method. Whereas the `apply` method is like a constructor which takes arguments and creates an object, the `unapply` takes an object and tries to give back the arguments. This is most often used in pattern matching and partial functions. -```tut +```scala mdoc import scala.util.Random object CustomerID { @@ -36,7 +36,7 @@ The `apply` method creates a `CustomerID` string from a `name`. The `unapply` do Since a value definition can use a pattern to introduce a new variable, an extractor can be used to initialize the variable, where the unapply method supplies the value. -```tut +```scala mdoc val customer2ID = CustomerID("Nico") val CustomerID(name) = customer2ID println(name) // prints Nico @@ -44,13 +44,13 @@ println(name) // prints Nico This is equivalent to `val name = CustomerID.unapply(customer2ID).get`. -```tut +```scala mdoc val CustomerID(name2) = "--asdfasdfasdf" ``` If there is no match, a `scala.MatchError` is thrown: -```tut:fail +```scala val CustomerID(name3) = "-asdfasdfasdf" ``` diff --git a/_tour/for-comprehensions.md b/_tour/for-comprehensions.md index 493f10a0bd..366e925578 100644 --- a/_tour/for-comprehensions.md +++ b/_tour/for-comprehensions.md @@ -15,7 +15,7 @@ Scala offers a lightweight notation for expressing *sequence comprehensions*. Co Here's an example: -```tut +```scala mdoc case class User(name: String, age: Int) val userBase = List( @@ -35,7 +35,7 @@ A `for` loop with a `yield` statement returns a result, the container type of wh Here is a more complicated example using two generators. It computes all pairs of numbers between `0` and `n-1` whose sum is equal to a given value `v`: -```tut +```scala mdoc def foo(n: Int, v: Int) = for (i <- 0 until n; j <- 0 until n if i + j == v) @@ -48,8 +48,7 @@ foo(10, 10) foreach { ``` Here `n == 10` and `v == 10`. On the first iteration, `i == 0` and `j == 0` so `i + j != v` and therefore nothing is yielded. `j` gets incremented 9 more times before `i` gets incremented to `1`. Without the `if` guard, this would simply print the following: -``` - +```scala (0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) (0, 9) (1, 0) ... ``` @@ -57,7 +56,7 @@ Note that comprehensions are not restricted to lists. Every datatype that suppor You can omit `yield` in a comprehension. In that case, comprehension will return `Unit`. This can be useful in case you need to perform side-effects. Here's a program equivalent to the previous one, but without using `yield`: -```tut +```scala mdoc:nest def foo(n: Int, v: Int) = for (i <- 0 until n; j <- 0 until n if i + j == v) diff --git a/_tour/generic-classes.md b/_tour/generic-classes.md index 035a6c0ee5..0b479d30df 100644 --- a/_tour/generic-classes.md +++ b/_tour/generic-classes.md @@ -14,7 +14,7 @@ Generic classes are classes which take a type as a parameter. They are particula ## Defining a generic class Generic classes take a type as a parameter within square brackets `[]`. One convention is to use the letter `A` as type parameter identifier, though any parameter name may be used. -```tut +```scala mdoc class Stack[A] { private var elements: List[A] = Nil def push(x: A): Unit = diff --git a/_tour/higher-order-functions.md b/_tour/higher-order-functions.md index 14a02d3620..c56846b81a 100644 --- a/_tour/higher-order-functions.md +++ b/_tour/higher-order-functions.md @@ -20,7 +20,7 @@ In a pure Object Oriented world a good practice is to avoid exposing methods par One of the most common examples is the higher-order function `map` which is available for collections in Scala. -```tut +```scala mdoc val salaries = Seq(20000, 70000, 40000) val doubleSalary = (x: Int) => x * 2 val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000) @@ -30,14 +30,14 @@ list of salaries. To shrink the code, we could make the function anonymous and pass it directly as an argument to map: -``` +```scala:nest val salaries = Seq(20000, 70000, 40000) val newSalaries = salaries.map(x => x * 2) // List(40000, 140000, 80000) ``` Notice how `x` is not declared as an Int in the above example. That's because the compiler can infer the type based on the type of function map expects (see [Currying](/tour/multiple-parameter-lists.html). An even more idiomatic way to write the same piece of code would be: -```tut +```scala mdoc:nest val salaries = Seq(20000, 70000, 40000) val newSalaries = salaries.map(_ * 2) ``` @@ -49,7 +49,7 @@ the previous example). ## Coercing methods into functions It is also possible to pass methods as arguments to higher-order functions because the Scala compiler will coerce the method into a function. -``` +```scala mdoc case class WeeklyWeatherForecast(temperatures: Seq[Double]) { private def convertCtoF(temp: Double) = temp * 1.8 + 32 @@ -64,7 +64,7 @@ Here the method `convertCtoF` is passed to the higher order function `map`. This One reason to use higher-order functions is to reduce redundant code. Let's say you wanted some methods that could raise someone's salaries by various factors. Without creating a higher-order function, it might look something like this: -```tut +```scala mdoc object SalaryRaiser { def smallPromotion(salaries: List[Double]): List[Double] = @@ -81,7 +81,7 @@ object SalaryRaiser { Notice how each of the three methods vary only by the multiplication factor. To simplify, you can extract the repeated code into a higher-order function like so: -```tut +```scala mdoc:nest object SalaryRaiser { private def promotion(salaries: List[Double], promotionFunction: Double => Double): List[Double] = @@ -108,7 +108,7 @@ Methods and functions usually express behaviours or data transformations, theref There are certain cases where you want to generate a function. Here's an example of a method that returns a function. -```tut +```scala mdoc def urlBuilder(ssl: Boolean, domainName: String): (String, String) => String = { val schema = if (ssl) "https://" else "http://" (endpoint: String, query: String) => s"$schema$domainName/$endpoint?$query" diff --git a/_tour/implicit-conversions.md b/_tour/implicit-conversions.md index 6f8f897d2f..4915f51daf 100644 --- a/_tour/implicit-conversions.md +++ b/_tour/implicit-conversions.md @@ -28,7 +28,7 @@ List(1, 2, 3) <= List(4, 5) An implicit method `Int => Ordered[Int]` is provided automatically through `scala.Predef.intWrapper`. An example of an implicit method `List[A] => Ordered[List[A]]` is provided below. -```tut +```scala mdoc import scala.language.implicitConversions implicit def list2ordered[A](x: List[A]) @@ -43,7 +43,7 @@ The implicitly imported object `scala.Predef` declares several aliases to freque For example, when calling a Java method that expects a `java.lang.Integer`, you are free to pass it a `scala.Int` instead. That's because Predef includes the following implicit conversions: -```tut +```scala mdoc import scala.language.implicitConversions implicit def int2Integer(x: Int) = diff --git a/_tour/implicit-parameters.md b/_tour/implicit-parameters.md index 7bb0b06d81..e67d992d79 100644 --- a/_tour/implicit-parameters.md +++ b/_tour/implicit-parameters.md @@ -21,7 +21,7 @@ A more detailed guide to where Scala looks for implicits can be found in [the FA In the following example we define a method `sum` which computes the sum of a list of elements using the monoid's `add` and `unit` operations. Please note that implicit values cannot be top-level. -```tut +```scala mdoc abstract class Monoid[A] { def add(x: A, y: A): A def unit: A diff --git a/_tour/inner-classes.md b/_tour/inner-classes.md index a2c5bf8e56..fc9e4f150a 100644 --- a/_tour/inner-classes.md +++ b/_tour/inner-classes.md @@ -14,7 +14,7 @@ In Scala it is possible to let classes have other classes as members. As opposed To illustrate the difference, we quickly sketch the implementation of a graph datatype: -```tut +```scala mdoc class Graph { class Node { var connectedNodes: List[Node] = Nil @@ -34,7 +34,7 @@ class Graph { ``` This program represents a graph as a list of nodes (`List[Node]`). Each node has a list of other nodes it's connected to (`connectedNodes`). The `class Node` is a _path-dependent type_ because it is nested in the `class Graph`. Therefore, all nodes in the `connectedNodes` must be created using the `newNode` from the same instance of `Graph`. -```tut +```scala mdoc val graph1: Graph = new Graph val node1: graph1.Node = graph1.newNode val node2: graph1.Node = graph1.newNode @@ -47,7 +47,7 @@ We have explicitly declared the type of `node1`, `node2`, and `node3` as `graph1 If we now have two graphs, the type system of Scala does not allow us to mix nodes defined within one graph with the nodes of another graph, since the nodes of the other graph have a different type. Here is an illegal program: -``` +```scala mdoc:fail val graph1: Graph = new Graph val node1: graph1.Node = graph1.newNode val node2: graph1.Node = graph1.newNode @@ -58,7 +58,7 @@ node1.connectTo(node3) // illegal! ``` The type `graph1.Node` is distinct from the type `graph2.Node`. In Java, the last line in the previous example program would have been correct. For nodes of both graphs, Java would assign the same type `Graph.Node`; i.e. `Node` is prefixed with class `Graph`. In Scala such a type can be expressed as well, it is written `Graph#Node`. If we want to be able to connect nodes of different graphs, we have to change the definition of our initial graph implementation in the following way: -```tut +```scala mdoc:nest class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil diff --git a/_tour/lower-type-bounds.md b/_tour/lower-type-bounds.md index bde9bd907f..a1cdb9648f 100644 --- a/_tour/lower-type-bounds.md +++ b/_tour/lower-type-bounds.md @@ -15,7 +15,7 @@ While [upper type bounds](upper-type-bounds.html) limit a type to a subtype of a Here is an example where this is useful: -```tut:fail +```scala mdoc:fail trait Node[+B] { def prepend(elem: B): Node[B] } @@ -37,7 +37,7 @@ However, this program does _not_ compile because the parameter `elem` in `prepen To fix this, we need to flip the variance of the type of the parameter `elem` in `prepend`. We do this by introducing a new type parameter `U` that has `B` as a lower type bound. -```tut +```scala mdoc trait Node[+B] { def prepend[U >: B](elem: U): Node[U] } @@ -54,7 +54,7 @@ case class Nil[+B]() extends Node[B] { ``` Now we can do the following: -```tut +```scala mdoc trait Bird case class AfricanSwallow() extends Bird case class EuropeanSwallow() extends Bird diff --git a/_tour/mixin-class-composition.md b/_tour/mixin-class-composition.md index 520a753e3b..fc362b2643 100644 --- a/_tour/mixin-class-composition.md +++ b/_tour/mixin-class-composition.md @@ -12,7 +12,7 @@ redirect_from: "/tutorials/tour/mixin-class-composition.html" --- Mixins are traits which are used to compose a class. -```tut +```scala mdoc abstract class A { val message: String } @@ -32,7 +32,7 @@ Class `D` has a superclass `B` and a mixin `C`. Classes can only have one superc Now let's look at a more interesting example starting with an abstract class: -```tut +```scala mdoc abstract class AbsIterator { type T def hasNext: Boolean @@ -43,7 +43,7 @@ The class has an abstract type `T` and the standard iterator methods. Next, we'll implement a concrete class (all abstract members `T`, `hasNext`, and `next` have implementations): -```tut +```scala mdoc class StringIterator(s: String) extends AbsIterator { type T = Char private var i = 0 @@ -59,7 +59,7 @@ class StringIterator(s: String) extends AbsIterator { Now let's create a trait which also extends `AbsIterator`. -```tut +```scala mdoc trait RichIterator extends AbsIterator { def foreach(f: T => Unit): Unit = while (hasNext) f(next()) } @@ -68,7 +68,7 @@ This trait implements `foreach` by continually calling the provided function `f: We would like to combine the functionality of `StringIterator` and `RichIterator` into a single class. -```tut +```scala mdoc class RichStringIter extends StringIterator("Scala") with RichIterator val richStringIter = new RichStringIter richStringIter.foreach(println) diff --git a/_tour/multiple-parameter-lists.md b/_tour/multiple-parameter-lists.md index bf0c0007ea..9aa3add880 100644 --- a/_tour/multiple-parameter-lists.md +++ b/_tour/multiple-parameter-lists.md @@ -16,7 +16,7 @@ Methods may have multiple parameter lists. Here is an example, as defined on the `Iterable` trait in Scala's collections API: -``` +```scala trait Iterable[A] { ... def foldLeft[B](z: B)(op: (B, A) => B): B @@ -29,7 +29,7 @@ trait Iterable[A] { Starting with an initial value of 0, `foldLeft` here applies the function `(m, n) => m + n` to each element in the List and the previous accumulated value. {% scalafiddle %} -```tut +```scala mdoc val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val res = numbers.foldLeft(0)((m, n) => m + n) println(res) // 55 @@ -45,26 +45,26 @@ Suggested use cases for multiple parameter lists include: It so happens that in Scala, type inference proceeds one parameter list at a time. Say you have the following method: -```tut +```scala mdoc def foldLeft1[A, B](as: List[A], b0: B, op: (B, A) => B) = ??? ``` Then you'd like to call it in the following way, but will find that it doesn't compile: -```tut:fail +```scala mdoc:fail def notPossible = foldLeft1(numbers, 0, _ + _) ``` you will have to call it like one of the below ways: -```tut +```scala mdoc def firstWay = foldLeft1[Int, Int](numbers, 0, _ + _) def secondWay = foldLeft1(numbers, 0, (a: Int, b: Int) => a + b) ``` That's because Scala won't be able to infer the type of the function `_ + _`, as it's still inferring `A` and `B`. By moving the parameter `op` to its own parameter list, `A` and `B` are inferred in the first parameter list. These inferred types will then be available to the second parameter list and `_ + _` will match the inferred type `(Int, Int) => Int` -```tut +```scala mdoc def foldLeft2[A, B](as: List[A], b0: B)(op: (B, A) => B) = ??? def possible = foldLeft2(numbers, 0)(_ + _) ``` @@ -78,7 +78,7 @@ To specify only certain parameters as [`implicit`](https://docs.scala-lang.org/t An example of this is: -``` +```scala mdoc def execute(arg: Int)(implicit ec: scala.concurrent.ExecutionContext) = ??? ``` @@ -88,7 +88,7 @@ When a method is called with a fewer number of parameter lists, then this will y For example, -```tut +```scala mdoc:nest val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val numberFunc = numbers.foldLeft(List[Int]()) _ diff --git a/_tour/named-arguments.md b/_tour/named-arguments.md index db54d951e3..3dc7a4a503 100644 --- a/_tour/named-arguments.md +++ b/_tour/named-arguments.md @@ -14,7 +14,7 @@ redirect_from: "/tutorials/tour/named-parameters.html" When calling methods, you can label the arguments with their parameter names like so: -```tut +```scala mdoc def printName(first: String, last: String): Unit = { println(first + " " + last) } @@ -25,7 +25,7 @@ printName(last = "Smith", first = "John") // Prints "John Smith" ``` Notice how the order of named arguments can be rearranged. However, if some arguments are named and others are not, the unnamed arguments must come first and in the order of their parameters in the method signature. -```tut:fail +```scala mdoc:fail printName(last = "Smith", "john") // error: positional after named argument ``` diff --git a/_tour/nested-functions.md b/_tour/nested-functions.md index 9dca50d5ee..a250fc2238 100644 --- a/_tour/nested-functions.md +++ b/_tour/nested-functions.md @@ -13,7 +13,7 @@ redirect_from: "/tutorials/tour/nested-functions.html" In Scala it is possible to nest method definitions. The following object provides a `factorial` method for computing the factorial of a given number: {% scalafiddle %} -```tut +```scala mdoc def factorial(x: Int): Int = { def fact(x: Int, accumulator: Int): Int = { if (x <= 1) accumulator diff --git a/_tour/operators.md b/_tour/operators.md index e16ed48080..38fd1a426c 100644 --- a/_tour/operators.md +++ b/_tour/operators.md @@ -22,7 +22,7 @@ However, it's easier to read as an infix operator: ## Defining and using operators You can use any legal identifier as an operator. This includes a name like `add` or a symbol(s) like `+`. -```tut +```scala mdoc case class Vec(x: Double, y: Double) { def +(that: Vec) = Vec(this.x + that.x, this.y + that.y) } @@ -36,7 +36,7 @@ vector3.y // 3.0 ``` The class Vec has a method `+` which we used to add `vector1` and `vector2`. Using parentheses, you can build up complex expressions with readable syntax. Here is the definition of class `MyBool` which includes methods `and` and `or`: -```tut +```scala mdoc case class MyBool(x: Boolean) { def and(that: MyBool): MyBool = if (x) that else this def or(that: MyBool): MyBool = if (x) this else that @@ -46,7 +46,7 @@ case class MyBool(x: Boolean) { It is now possible to use `and` and `or` as infix operators: -```tut +```scala mdoc def not(x: MyBool) = x.negate def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y) ``` diff --git a/_tour/packages-and-imports.md b/_tour/packages-and-imports.md index d9f2491a6a..f18f8ae5e3 100644 --- a/_tour/packages-and-imports.md +++ b/_tour/packages-and-imports.md @@ -65,7 +65,7 @@ import users.{UserPreferences => UPrefs} // import and rename for convenience One way in which Scala is different from Java is that imports can be used anywhere: -```tut +```scala mdoc def sqrtplus1(x: Int) = { import scala.math.sqrt sqrt(x) + 1.0 diff --git a/_tour/pattern-matching.md b/_tour/pattern-matching.md index bca157058e..0e225b2b65 100644 --- a/_tour/pattern-matching.md +++ b/_tour/pattern-matching.md @@ -15,7 +15,7 @@ Pattern matching is a mechanism for checking a value against a pattern. A succes ## Syntax A match expression has a value, the `match` keyword, and at least one `case` clause. -```tut +```scala mdoc import scala.util.Random val x: Int = Random.nextInt(10) @@ -30,7 +30,7 @@ x match { The `val x` above is a random integer between 0 and 10. `x` becomes the left operand of the `match` operator and on the right is an expression with four cases. The last case `_` is a "catch all" case for any other possible `Int` values. Cases are also called _alternatives_. Match expressions have a value. -```tut +```scala mdoc def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" @@ -45,7 +45,7 @@ This match expression has a type String because all of the cases return String. Case classes are especially useful for pattern matching. -```tut +```scala mdoc abstract class Notification case class Email(sender: String, title: String, body: String) extends Notification @@ -111,7 +111,7 @@ In the `case Email(sender, _, _) if importantPeopleInfo.contains(sender)`, the p ## Matching on type only You can match on the type like so: -```tut +```scala mdoc abstract class Device case class Phone(model: String) extends Device { def screenOff = "Turning screen off" @@ -130,7 +130,7 @@ def goIdle(device: Device) = device match { ## Sealed classes Traits and classes can be marked `sealed` which means all subtypes must be declared in the same file. This assures that all subtypes are known. -```tut +```scala mdoc sealed abstract class Furniture case class Couch() extends Furniture case class Chair() extends Furniture @@ -149,4 +149,4 @@ Scala also allows the definition of patterns independently of case classes, usin ## More resources -* More details on match expressions in the [Scala Book](/overviews/scala-book/match-expressions.html) \ No newline at end of file +* More details on match expressions in the [Scala Book](/overviews/scala-book/match-expressions.html) diff --git a/_tour/polymorphic-methods.md b/_tour/polymorphic-methods.md index a6cdb6f90a..6565adcd5b 100644 --- a/_tour/polymorphic-methods.md +++ b/_tour/polymorphic-methods.md @@ -16,7 +16,7 @@ Methods in Scala can be parameterized by type as well as value. The syntax is si Here is an example: -```tut +```scala mdoc def listOfDuplicates[A](x: A, length: Int): List[A] = { if (length < 1) Nil diff --git a/_tour/regular-expression-patterns.md b/_tour/regular-expression-patterns.md index cd7e61be5e..aa51821463 100644 --- a/_tour/regular-expression-patterns.md +++ b/_tour/regular-expression-patterns.md @@ -13,7 +13,7 @@ redirect_from: "/tutorials/tour/regular-expression-patterns.html" Regular expressions are strings which can be used to find patterns (or lack thereof) in data. Any string can be converted to a regular expression using the `.r` method. -```tut +```scala mdoc import scala.util.matching.Regex val numberPattern: Regex = "[0-9]".r @@ -29,7 +29,7 @@ In the above example, the `numberPattern` is a `Regex` You can also search for groups of regular expressions using parentheses. -```tut +```scala mdoc import scala.util.matching.Regex val keyValPattern: Regex = "([0-9a-zA-Z- ]+): ([0-9a-zA-Z-#()/. ]+)".r diff --git a/_tour/self-types.md b/_tour/self-types.md index e1a80388fb..49110f23f9 100644 --- a/_tour/self-types.md +++ b/_tour/self-types.md @@ -16,7 +16,7 @@ Self-types are a way to declare that a trait must be mixed into another trait, e 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. 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 =>`). -```tut +```scala mdoc trait User { def username: String } diff --git a/_tour/singleton-objects.md b/_tour/singleton-objects.md index e50055dc2a..037e855b0b 100644 --- a/_tour/singleton-objects.md +++ b/_tour/singleton-objects.md @@ -16,7 +16,7 @@ As a top-level value, an object is a singleton. As a member of an enclosing class or as a local value, it behaves exactly like a lazy val. # Defining a singleton object An object is a value. The definition of an object looks like a class, but uses the keyword `object`: -```tut +```scala mdoc object Box ``` @@ -73,7 +73,7 @@ circle1.area The `class Circle` has a member `area` which is specific to each instance, and the singleton `object Circle` has a method `calculateArea` which is available to every instance. The companion object can also contain factory methods: -```tut +```scala mdoc class Email(val username: String, val domainName: String) object Email { @@ -107,4 +107,4 @@ When using a companion object from Java code, the members will be defined in a c ## More resources -* Learn more about Companion objects in the [Scala Book](/overviews/scala-book/companion-objects.html) \ No newline at end of file +* Learn more about Companion objects in the [Scala Book](/overviews/scala-book/companion-objects.html) diff --git a/_tour/traits.md b/_tour/traits.md index 65cc279a04..6500490b7d 100644 --- a/_tour/traits.md +++ b/_tour/traits.md @@ -17,12 +17,12 @@ Traits are used to share interfaces and fields between classes. They are similar ## Defining a trait A minimal trait is simply the keyword `trait` and an identifier: -```tut +```scala mdoc trait HairColor ``` Traits become especially useful as generic types and with abstract methods. -```tut +```scala mdoc trait Iterator[A] { def hasNext: Boolean def next(): A @@ -33,7 +33,7 @@ Extending the `trait Iterator[A]` requires a type `A` and implementations of the ## Using traits Use the `extends` keyword to extend a trait. Then implement any abstract members of the trait using the `override` keyword: -```tut +```scala mdoc:nest trait Iterator[A] { def hasNext: Boolean def next(): A @@ -60,7 +60,7 @@ This `IntIterator` class takes a parameter `to` as an upper bound. It `extends I ## Subtyping Where a given trait is required, a subtype of the trait can be used instead. -```tut +```scala mdoc import scala.collection.mutable.ArrayBuffer trait Pet { diff --git a/_tour/tuples.md b/_tour/tuples.md index 15d8aef6cf..3f684f63bb 100644 --- a/_tour/tuples.md +++ b/_tour/tuples.md @@ -18,7 +18,7 @@ Tuples are especially handy for returning multiple values from a method. A tuple with two elements can be created as follows: -```tut +```scala mdoc val ingredient = ("Sugar" , 25) ``` @@ -35,7 +35,7 @@ Each class has as many type parameters as it has elements. One way of accessing tuple elements is by position. The individual elements are named `_1`, `_2`, and so forth. -```tut +```scala mdoc println(ingredient._1) // Sugar println(ingredient._2) // 25 ``` @@ -44,7 +44,7 @@ println(ingredient._2) // 25 A tuple can also be taken apart using pattern matching: -```tut +```scala mdoc val (name, quantity) = ingredient println(name) // Sugar println(quantity) // 25 @@ -55,7 +55,7 @@ is `Int`. Here is another example of pattern-matching a tuple: -```tut +```scala mdoc val planets = List(("Mercury", 57.9), ("Venus", 108.2), ("Earth", 149.6), ("Mars", 227.9), ("Jupiter", 778.3)) @@ -68,7 +68,7 @@ planets.foreach{ Or, in `for` comprehension: -```tut +```scala mdoc val numPairs = List((2, 5), (3, -7), (20, 56)) for ((a, b) <- numPairs) { println(a * b) diff --git a/_tour/type-inference.md b/_tour/type-inference.md index 38b8295eda..271906fe3c 100644 --- a/_tour/type-inference.md +++ b/_tour/type-inference.md @@ -12,19 +12,19 @@ The Scala compiler can often infer the type of an expression so you don't have t ## Omitting the type -```tut +```scala mdoc val businessName = "Montreux Jazz Café" ``` The compiler can detect that `businessName` is a String. It works similarly with methods: -```tut +```scala mdoc def squareOf(x: Int) = x * x ``` The compiler can infer that the return type is an `Int`, so no explicit return type is required. For recursive methods, the compiler is not able to infer a result type. Here is a program which will fail the compiler for this reason: -```tut:fail +```scala mdoc:fail def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) ``` @@ -32,7 +32,7 @@ It is also not compulsory to specify type parameters when [polymorphic methods]( Here are two examples: -```tut +```scala mdoc case class MyPair[A, B](x: A, y: B) val p = MyPair(1, "scala") // type: MyPair[Int, String] @@ -46,7 +46,7 @@ The compiler uses the types of the arguments of `MyPair` to figure out what type The compiler never infers method parameter types. However, in certain cases, it can infer anonymous function parameter types when the function is passed as argument. -```tut +```scala mdoc Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) ``` @@ -58,13 +58,13 @@ It is generally considered more readable to declare the type of members exposed Also, type inference can sometimes infer a too-specific type. Suppose we write: -```tut +```scala var obj = null ``` We can't then go on and make this reassignment: -```tut:fail +```scala mdoc:fail obj = new AnyRef ``` diff --git a/_tour/unified-types.md b/_tour/unified-types.md index fa3d97481a..5d4fe4947c 100644 --- a/_tour/unified-types.md +++ b/_tour/unified-types.md @@ -25,7 +25,7 @@ In Scala, all values have a type, including numerical values and functions. The Here is an example that demonstrates that strings, integers, characters, boolean values, and functions are all objects just like every other object: -```tut +```scala mdoc val list: List[Any] = List( "a string", 732, // an integer @@ -55,7 +55,7 @@ Value types can be cast in the following way: For example: -```tut +```scala mdoc val x: Long = 987654321 val y: Float = x // 9.8765434E8 (note that some precision is lost in this case) diff --git a/_tour/upper-type-bounds.md b/_tour/upper-type-bounds.md index 37c7a85d86..8c4b5815c7 100644 --- a/_tour/upper-type-bounds.md +++ b/_tour/upper-type-bounds.md @@ -13,7 +13,7 @@ redirect_from: "/tutorials/tour/upper-type-bounds.html" In Scala, [type parameters](generic-classes.html) and [abstract type members](abstract-type-members.html) may be constrained by a type bound. Such type bounds limit the concrete values of the type variables and possibly reveal more information about the members of such types. An _upper type bound_ `T <: A` declares that type variable `T` refers to a subtype of type `A`. Here is an example that demonstrates upper type bound for a type parameter of class `PetContainer`: -```tut +```scala mdoc abstract class Animal { def name: String } @@ -40,7 +40,7 @@ val dogContainer = new PetContainer[Dog](new Dog) val catContainer = new PetContainer[Cat](new Cat) ``` -```tut:fail +```scala mdoc:fail // this would not compile val lionContainer = new PetContainer[Lion](new Lion) ``` diff --git a/_tour/variances.md b/_tour/variances.md index 6d70f615dc..69f371e81e 100644 --- a/_tour/variances.md +++ b/_tour/variances.md @@ -12,7 +12,7 @@ redirect_from: "/tutorials/tour/variances.html" Variance is the correlation of subtyping relationships of complex types and the subtyping relationships of their component types. Scala supports variance annotations of type parameters of [generic classes](generic-classes.html), to allow them to be covariant, contravariant, or invariant if no annotations are used. The use of variance in the type system allows us to make intuitive connections between complex types, whereas the lack of variance can restrict the reuse of a class abstraction. -```tut +```scala mdoc class Foo[+A] // A covariant class class Bar[-A] // A contravariant class class Baz[A] // An invariant class @@ -24,7 +24,7 @@ A type parameter `T` of a generic class can be made covariant by using the annot Consider this simple class structure: -```tut +```scala mdoc abstract class Animal { def name: String } @@ -36,7 +36,7 @@ Both `Cat` and `Dog` are subtypes of `Animal`. The Scala standard library has a In the following example, the method `printAnimalNames` will accept a list of animals as an argument and print their names each on a new line. If `List[A]` were not covariant, the last two method calls would not compile, which would severely limit the usefulness of the `printAnimalNames` method. -```tut +```scala mdoc def printAnimalNames(animals: List[Animal]): Unit = animals.foreach { animal => println(animal.name) @@ -58,7 +58,7 @@ A type parameter `A` of a generic class can be made contravariant by using the a Consider the `Cat`, `Dog`, and `Animal` classes defined above for the following example: -```tut +```scala mdoc abstract class Printer[-A] { def print(value: A): Unit } @@ -66,7 +66,7 @@ abstract class Printer[-A] { A `Printer[A]` is a simple class that knows how to print out some type `A`. Let's define some subclasses for specific types: -```tut +```scala mdoc class AnimalPrinter extends Printer[Animal] { def print(animal: Animal): Unit = println("The animal's name is: " + animal.name) @@ -80,7 +80,7 @@ class CatPrinter extends Printer[Cat] { If a `Printer[Cat]` knows how to print any `Cat` to the console, and a `Printer[Animal]` knows how to print any `Animal` to the console, it makes sense that a `Printer[Animal]` would also know how to print any `Cat`. The inverse relationship does not apply, because a `Printer[Cat]` does not know how to print any `Animal` to the console. Therefore, we should be able to use a `Printer[Animal]` in place of `Printer[Cat]`, if we wish, and making `Printer[A]` contravariant allows us to do exactly that. -```tut +```scala mdoc def printMyCat(printer: Printer[Cat], cat: Cat): Unit = printer.print(cat) @@ -102,7 +102,7 @@ The animal's name is: Boots Generic classes in Scala are invariant by default. This means that they are neither covariant nor contravariant. In the context of the following example, `Container` class is invariant. A `Container[Cat]` is _not_ a `Container[Animal]`, nor is the reverse true. -```tut +```scala mdoc class Container[A](value: A) { private var _value: A = value def getValue: A = _value @@ -129,7 +129,7 @@ Another example that can help one understand variance is `trait Function1[-T, +R Assume the similar `Cat`, `Dog`, `Animal` inheritance tree used earlier, plus the following: -```tut +```scala mdoc abstract class SmallAnimal extends Animal case class Mouse(name: String) extends SmallAnimal ``` diff --git a/_zh-cn/overviews/reflection/thread-safety.md b/_zh-cn/overviews/reflection/thread-safety.md index 86acc1c247..e601c8e7e8 100644 --- a/_zh-cn/overviews/reflection/thread-safety.md +++ b/_zh-cn/overviews/reflection/thread-safety.md @@ -44,4 +44,4 @@ language: zh-cn * 如果您正在编写一个没有显式创建线程的宏那就没有问题。 * 线程或参与者(actors)混在一起的运行时反射可能很危险。 * 多个带有`TypeTag`上下文边界的线程调用方法可能导致不确定的结果。 -* 请查看 [SI-6240](https://issues.scala-lang.org/browse/SI-6240),以了解我们在此问题上的进展。 \ No newline at end of file +* 请查看 [SI-6240](https://issues.scala-lang.org/browse/SI-6240),以了解我们在此问题上的进展。 diff --git a/_zh-cn/tour/abstract-type-members.md b/_zh-cn/tour/abstract-type-members.md index 4ef5e918d4..3fbbb8a487 100644 --- a/_zh-cn/tour/abstract-type-members.md +++ b/_zh-cn/tour/abstract-type-members.md @@ -13,7 +13,7 @@ previous-page: inner-classes 特质和抽象类可以包含一个抽象类型成员,意味着实际类型可由具体实现来确定。例如: -```tut +```scala mdoc trait Buffer { type T val element: T @@ -21,7 +21,7 @@ trait Buffer { ``` 这里定义的抽象类型`T`是用来描述成员`element`的类型的。通过抽象类来扩展这个特质后,就可以添加一个类型上边界来让抽象类型`T`变得更加具体。 -```tut +```scala mdoc abstract class SeqBuffer extends Buffer { type U type T <: Seq[U] @@ -32,7 +32,7 @@ abstract class SeqBuffer extends Buffer { 含有抽象类型成员的特质或类([classes](classes.html))经常和匿名类的初始化一起使用。为了能够阐明问题,下面看一段程序,它处理一个涉及整型列表的序列缓冲区。 -```tut +```scala mdoc abstract class IntSeqBuffer extends SeqBuffer { type U = Int } @@ -51,7 +51,7 @@ println("content = " + buf.element) 把抽象类型成员转成类的类型参数或者反过来,也是可行的。如下面这个版本只用了类的类型参数来转换上面的代码: -```tut +```scala mdoc:nest abstract class Buffer[+T] { val element: T } diff --git a/_zh-cn/tour/annotations.md b/_zh-cn/tour/annotations.md index c69d1fbc1f..56992045d6 100644 --- a/_zh-cn/tour/annotations.md +++ b/_zh-cn/tour/annotations.md @@ -26,7 +26,7 @@ object DeprecationDemo extends App { ## 确保编码正确性的注解 如果不满足条件,某些注解实际上会导致编译失败。 例如,注解 `@tailrec` 确保方法是 [尾递归](https://en.wikipedia.org/wiki/Tail_call)。 尾递归可以保持内存需求不变。 以下是它在计算阶乘的方法中的用法: -```tut +```scala mdoc import scala.annotation.tailrec def factorial(x: Int): Int = { diff --git a/_zh-cn/tour/basics.md b/_zh-cn/tour/basics.md index 70d7b1992c..55bbc97a4f 100644 --- a/_zh-cn/tour/basics.md +++ b/_zh-cn/tour/basics.md @@ -27,13 +27,13 @@ previous-page: tour-of-scala ## 表达式 表达式是可计算的语句。 -``` +```scala mdoc 1 + 1 ``` 你可以使用`println`来输出表达式的结果。 {% scalafiddle %} -```tut +```scala mdoc println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! @@ -45,7 +45,7 @@ println("Hello," + " world!") // Hello, world! 你可以使用`val`关键字来给表达式的结果命名。 -```tut +```scala mdoc val x = 1 + 1 println(x) // 2 ``` @@ -54,13 +54,13 @@ println(x) // 2 常量(`values`)不能重新被赋值。 -```tut:fail +```scala mdoc:fail x = 3 // This does not compile. ``` 常量(`values`)的类型可以被推断,或者你也可以显示地声明类型,例如: -```tut +```scala mdoc:nest val x: Int = 1 + 1 ``` @@ -70,7 +70,7 @@ val x: Int = 1 + 1 除了可以重新赋值,变量和常量类似。你可以使用`var`关键字来定义一个变量。 -```tut +```scala mdoc:nest var x = 1 + 1 x = 3 // This compiles because "x" is declared with the "var" keyword. println(x * x) // 9 @@ -78,7 +78,7 @@ println(x * x) // 9 和常量一样,你可以显示地声明类型: -```tut +```scala mdoc:nest var x: Int = 1 + 1 ``` @@ -89,7 +89,7 @@ var x: Int = 1 + 1 代码块中最后一个表达式的结果,也正是整个块的结果。 -```tut +```scala mdoc println({ val x = 1 + 1 x + 1 @@ -102,7 +102,7 @@ println({ 你可以定义一个匿名函数(即没有名字),来返回一个给定整数加一的结果。 -```tut +```scala mdoc (x: Int) => x + 1 ``` @@ -111,7 +111,7 @@ println({ 你也可以给函数命名。 {% scalafiddle %} -```tut +```scala mdoc val addOne = (x: Int) => x + 1 println(addOne(1)) // 2 ``` @@ -120,7 +120,7 @@ println(addOne(1)) // 2 函数可带有多个参数。 {% scalafiddle %} -```tut +```scala mdoc val add = (x: Int, y: Int) => x + y println(add(1, 2)) // 3 ``` @@ -128,7 +128,7 @@ println(add(1, 2)) // 3 或者不带参数。 -```tut +```scala mdoc val getTheAnswer = () => 42 println(getTheAnswer()) // 42 ``` @@ -140,7 +140,7 @@ println(getTheAnswer()) // 42 方法由`def`关键字定义。`def`后面跟着一个名字、参数列表、返回类型和方法体。 {% scalafiddle %} -```tut +```scala mdoc:nest def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3 ``` @@ -151,7 +151,7 @@ println(add(1, 2)) // 3 方法可以接受多个参数列表。 {% scalafiddle %} -```tut +```scala mdoc def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9 ``` @@ -159,7 +159,7 @@ println(addThenMultiply(1, 2)(3)) // 9 或者没有参数列表。 -```tut +```scala mdoc def name: String = System.getProperty("user.name") println("Hello, " + name + "!") ``` @@ -169,7 +169,7 @@ println("Hello, " + name + "!") 方法也可以有多行的表达式。 {% scalafiddle %} -```tut +```scala mdoc def getSquareString(input: Double): String = { val square = input * input square.toString @@ -184,7 +184,7 @@ println(getSquareString(2.5)) // 6.25 你可以使用`class`关键字定义一个类,后面跟着它的名字和构造参数。 -```tut +```scala mdoc class Greeter(prefix: String, suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) @@ -194,7 +194,7 @@ class Greeter(prefix: String, suffix: String) { 你可以使用`new`关键字创建一个类的实例。 -```tut +```scala mdoc val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` @@ -205,13 +205,13 @@ greeter.greet("Scala developer") // Hello, Scala developer! Scala有一种特殊的类叫做样例类(case class)。默认情况下,样例类一般用于不可变对象,并且可作值比较。你可以使用`case class`关键字来定义样例类。 -```tut +```scala mdoc case class Point(x: Int, y: Int) ``` 你可以不用`new`关键字来实例化样例类。 -```tut +```scala mdoc val point = Point(1, 2) val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2) @@ -219,7 +219,7 @@ val yetAnotherPoint = Point(2, 2) 并且它们的值可以进行比较。 -```tut +```scala mdoc if (point == anotherPoint) { println(point + " and " + anotherPoint + " are the same.") } else { @@ -241,7 +241,7 @@ if (point == yetAnotherPoint) { 你可以使用`object`关键字定义对象。 -```tut +```scala mdoc object IdFactory { private var counter = 0 def create(): Int = { @@ -253,7 +253,7 @@ object IdFactory { 你可以通过引用它的名字来访问一个对象。 -```tut +```scala mdoc val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() @@ -268,7 +268,7 @@ println(newerId) // 2 你可以使用`trait`关键字定义特质。 -```tut +```scala mdoc:nest trait Greeter { def greet(name: String): Unit } @@ -277,7 +277,7 @@ trait Greeter { 特质也可以有默认的实现。 {% scalafiddle %} -```tut +```scala mdoc:reset trait Greeter { def greet(name: String): Unit = println("Hello, " + name + "!") @@ -286,7 +286,7 @@ trait Greeter { 你可以使用`extends`关键字来继承特质,使用`override`关键字来覆盖默认的实现。 -```tut +```scala mdoc class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { @@ -313,7 +313,7 @@ customGreeter.greet("Scala developer") // How are you, Scala developer? 通过使用对象,你可以如下所示来定义一个主方法。 -```tut +```scala mdoc object Main { def main(args: Array[String]): Unit = println("Hello, Scala developer!") diff --git a/_zh-cn/tour/by-name-parameters.md b/_zh-cn/tour/by-name-parameters.md index 31eae14e22..ce3ad1f726 100644 --- a/_zh-cn/tour/by-name-parameters.md +++ b/_zh-cn/tour/by-name-parameters.md @@ -12,13 +12,13 @@ previous-page: operators --- _传名参数_ 仅在被使用时触发实际参数的求值运算。 它们与 _传值参数_ 正好相反。 要将一个参数变为传名参数,只需在它的类型前加上 `=>`。 -```tut +```scala mdoc def calculate(input: => Int) = input * 37 ``` 传名参数的优点是,如果它们在函数体中未被使用,则不会对它们进行求值。 另一方面,传值参数的优点是它们仅被计算一次。 以下是我们如何实现一个 while 循环的例子: -```tut +```scala mdoc def whileLoop(condition: => Boolean)(body: => Unit): Unit = if (condition) { body diff --git a/_zh-cn/tour/case-classes.md b/_zh-cn/tour/case-classes.md index b9346c1b4b..cbff24d6e9 100644 --- a/_zh-cn/tour/case-classes.md +++ b/_zh-cn/tour/case-classes.md @@ -15,7 +15,7 @@ previous-page: multiple-parameter-lists ## 定义一个案例类 一个最简单的案例类定义由关键字`case class`,类名,参数列表(可为空)组成: -```tut +```scala mdoc case class Book(isbn: String) val frankenstein = Book("978-0486282114") diff --git a/_zh-cn/tour/classes.md b/_zh-cn/tour/classes.md index 58acc8fc2a..e01dece08f 100644 --- a/_zh-cn/tour/classes.md +++ b/_zh-cn/tour/classes.md @@ -17,14 +17,14 @@ Scala中的类是用于创建对象的蓝图,其中包含了方法、常量、 ## 类定义 一个最简的类的定义就是关键字`class`+标识符,类名首字母应大写。 -```tut +```scala mdoc class User val user1 = new User ``` 关键字`new`被用于创建类的实例。`User`由于没有定义任何构造器,因而只有一个不带任何参数的默认构造器。然而,你通常需要一个构造器和类体。下面是类定义的一个例子: -```tut +```scala mdoc class Point(var x: Int, var y: Int) { def move(dx: Int, dy: Int): Unit = { @@ -47,7 +47,7 @@ println(point1) // prints (2, 3) 构造器可以通过提供一个默认值来拥有可选参数: -```tut +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val origin = new Point // x and y are both set to 0 @@ -57,7 +57,7 @@ println(point1.x) // prints 1 ``` 在这个版本的`Point`类中,`x`和`y`拥有默认值`0`所以没有必传参数。然而,因为构造器是从左往右读取参数,所以如果仅仅要传个`y`的值,你需要带名传参。 -``` +```scala mdoc:nest class Point(var x: Int = 0, var y: Int = 0) val point2 = new Point(y=2) println(point2.y) // prints 2 @@ -67,7 +67,7 @@ println(point2.y) // prints 2 ## 私有成员和Getter/Setter语法 成员默认是公有(`public`)的。使用`private`访问修饰符可以在类外部隐藏它们。 -```tut +```scala mdoc:nest class Point { private var _x = 0 private var _y = 0 @@ -93,14 +93,14 @@ point1.y = 101 // prints the warning 在这个版本的`Point`类中,数据存在私有变量`_x`和`_y`中。`def x`和`def y`方法用于访问私有数据。`def x_=`和`def y_=`是为了验证和给`_x`和`_y`赋值。注意下对于setter方法的特殊语法:这个方法在getter方法的后面加上`_=`,后面跟着参数。 主构造方法中带有`val`和`var`的参数是公有的。然而由于`val`是不可变的,所以不能像下面这样去使用。 -``` +```scala mdoc:fail class Point(val x: Int, val y: Int) val point = new Point(1, 2) point.x = 3 // <-- does not compile ``` 不带`val`或`var`的参数是私有的,仅在类中可见。 -``` +```scala mdoc:fail class Point(x: Int, y: Int) val point = new Point(1, 2) point.x // <-- does not compile diff --git a/_zh-cn/tour/compound-types.md b/_zh-cn/tour/compound-types.md index 467f0738c0..9c36707c67 100644 --- a/_zh-cn/tour/compound-types.md +++ b/_zh-cn/tour/compound-types.md @@ -15,7 +15,7 @@ previous-page: abstract-type-members 假设我们有两个特质 `Cloneable` 和 `Resetable`: -```tut +```scala mdoc trait Cloneable extends java.lang.Cloneable { override def clone(): Cloneable = { super.clone().asInstanceOf[Cloneable] diff --git a/_zh-cn/tour/default-parameter-values.md b/_zh-cn/tour/default-parameter-values.md index 7860abca4c..67db867770 100644 --- a/_zh-cn/tour/default-parameter-values.md +++ b/_zh-cn/tour/default-parameter-values.md @@ -13,7 +13,7 @@ previous-page: annotations Scala具备给参数提供默认值的能力,这样调用者就可以忽略这些具有默认值的参数。 -```tut +```scala mdoc def log(message: String, level: String = "INFO") = println(s"$level: $message") log("System starting") // prints INFO: System starting @@ -22,7 +22,7 @@ log("User not found", "WARNING") // prints WARNING: User not found 上面的参数level有默认值,所以是可选的。最后一行中传入的参数`"WARNING"`重写了默认值`"INFO"`。在Java中,我们可以通过带有可选参数的重载方法达到同样的效果。不过,只要调用方忽略了一个参数,其他参数就必须要带名传入。 -```tut +```scala mdoc class Point(val x: Double = 0, val y: Double = 0) val point1 = new Point(y = 1) @@ -31,7 +31,7 @@ val point1 = new Point(y = 1) 注意从Java代码中调用时,Scala中的默认参数则是必填的(非可选),如: -```tut +```scala mdoc:nest // Point.scala class Point(val x: Double = 0, val y: Double = 0) ``` diff --git a/_zh-cn/tour/extractor-objects.md b/_zh-cn/tour/extractor-objects.md index f61d64f91a..d6d75aaad8 100644 --- a/_zh-cn/tour/extractor-objects.md +++ b/_zh-cn/tour/extractor-objects.md @@ -13,7 +13,7 @@ previous-page: regular-expression-patterns 提取器对象是一个包含有 `unapply` 方法的单例对象。`apply` 方法就像一个构造器,接受参数然后创建一个实例对象,反之 `unapply` 方法接受一个实例对象然后返回最初创建它所用的参数。提取器常用在模式匹配和偏函数中。 -```tut +```scala mdoc import scala.util.Random object CustomerID { @@ -37,7 +37,7 @@ customer1ID match { 因为变量定义可以使用模式引入变量,提取器可以用来初始化这个变量,使用 unapply 方法来生成值。 -```tut +```scala mdoc val customer2ID = CustomerID("Nico") val CustomerID(name) = customer2ID println(name) // prints Nico @@ -45,13 +45,13 @@ println(name) // prints Nico 上面的代码等价于 `val name = CustomerID.unapply(customer2ID).get`。 -```tut +```scala mdoc val CustomerID(name2) = "--asdfasdfasdf" ``` 如果没有匹配的值,会抛出 `scala.MatchError`: -```tut:fail +```scala val CustomerID(name3) = "-asdfasdfasdf" ``` diff --git a/_zh-cn/tour/for-comprehensions.md b/_zh-cn/tour/for-comprehensions.md index 6c0ebfee41..f1fe6a5d72 100644 --- a/_zh-cn/tour/for-comprehensions.md +++ b/_zh-cn/tour/for-comprehensions.md @@ -15,7 +15,7 @@ Scala 提供一个轻量级的标记方式用来表示 *序列推导*。推导 看下例: -```tut +```scala mdoc case class User(name: String, age: Int) val userBase = List(User("Travis", 28), @@ -32,7 +32,7 @@ twentySomethings.foreach(name => println(name)) // prints Travis Dennis 下面这个例子复杂一些,使用了两个生成器。它计算了 `0` 到 `n-1` 的所有两两求和为 `v` 的数字的组合: -```tut +```scala mdoc def foo(n: Int, v: Int) = for (i <- 0 until n; j <- i until n if i + j == v) @@ -45,8 +45,7 @@ foo(10, 10) foreach { ``` 这里 `n == 10` 和 `v == 10`。在第一次迭代时,`i == 0` 并且 `j == 0` 所以 `i + j != v` 因此没有返回值被生成。在 `i` 的值递增到 `1` 之前,`j` 的值又递增了 9 次。如果没有 `if` 语句过滤,上面的例子只会打印出如下的结果: -``` - +```scala (0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) (0, 9) (1, 1) ... ``` @@ -54,7 +53,7 @@ foo(10, 10) foreach { 你可以在使用 for 表达式时省略 `yield` 语句。此时会返回 `Unit`。当你想要执行一些副作用的时候这很有用。下面的例子输出和上面相同的结果,但是没有使用 `yield`: -```tut +```scala mdoc:nest def foo(n: Int, v: Int) = for (i <- 0 until n; j <- i until n if i + j == v) diff --git a/_zh-cn/tour/generic-classes.md b/_zh-cn/tour/generic-classes.md index 944105906c..7867479472 100644 --- a/_zh-cn/tour/generic-classes.md +++ b/_zh-cn/tour/generic-classes.md @@ -14,7 +14,7 @@ previous-page: extractor-objects ## 定义一个泛型类 泛型类使用方括号 `[]` 来接受类型参数。一个惯例是使用字母 `A` 作为参数标识符,当然你可以使用任何参数名称。 -```tut +```scala mdoc class Stack[A] { private var elements: List[A] = Nil def push(x: A) { elements = x :: elements } diff --git a/_zh-cn/tour/higher-order-functions.md b/_zh-cn/tour/higher-order-functions.md index 5002faf72f..c5112c1805 100644 --- a/_zh-cn/tour/higher-order-functions.md +++ b/_zh-cn/tour/higher-order-functions.md @@ -27,7 +27,7 @@ val salaries = Seq(20000, 70000, 40000) val newSalaries = salaries.map(x => x * 2) // List(40000, 140000, 80000) ``` 注意在上述示例中`x`没有被显式声明为Int类型,这是因为编译器能够根据map函数期望的类型推断出`x`的类型。对于上述代码,一种更惯用的写法为: -```tut +```scala mdoc val salaries = Seq(20000, 70000, 40000) val newSalaries = salaries.map(_ * 2) ``` @@ -47,7 +47,7 @@ case class WeeklyWeatherForecast(temperatures: Seq[Double]) { ## 接收函数作为参数的函数 使用高阶函数的一个原因是减少冗余的代码。比方说需要写几个方法以通过不同方式来提升员工工资,若不使用高阶函数,代码可能像这样: -```tut +```scala mdoc object SalaryRaiser { def smallPromotion(salaries: List[Double]): List[Double] = @@ -63,7 +63,7 @@ object SalaryRaiser { 注意这三个方法的差异仅仅是提升的比例不同,为了简化代码,其实可以把重复的代码提到一个高阶函数中: -```tut +```scala mdoc:nest object SalaryRaiser { private def promotion(salaries: List[Double], promotionFunction: Double => Double): List[Double] = @@ -86,7 +86,7 @@ object SalaryRaiser { 有一些情况你希望生成一个函数, 比如: -```tut +```scala mdoc def urlBuilder(ssl: Boolean, domainName: String): (String, String) => String = { val schema = if (ssl) "https://" else "http://" (endpoint: String, query: String) => s"$schema$domainName/$endpoint?$query" diff --git a/_zh-cn/tour/implicit-conversions.md b/_zh-cn/tour/implicit-conversions.md index dc52248ffd..48049bc249 100644 --- a/_zh-cn/tour/implicit-conversions.md +++ b/_zh-cn/tour/implicit-conversions.md @@ -29,7 +29,7 @@ List(1, 2, 3) <= List(4, 5) 在 `scala.Predef.intWrapper` 已经自动提供了一个隐式方法 `Int => Ordered[Int]`。下面提供了一个隐式方法 `List[A] => Ordered[List[A]]` 的例子。 -```tut +```scala mdoc import scala.language.implicitConversions implicit def list2ordered[A](x: List[A]) @@ -44,7 +44,7 @@ implicit def list2ordered[A](x: List[A]) 例如,当调用一个接受 `java.lang.Integer` 作为参数的 Java 方法时,你完全可以传入一个 `scala.Int`。那是因为 Predef 包含了以下的隐式转换: -```tut +```scala mdoc import scala.language.implicitConversions implicit def int2Integer(x: Int) = diff --git a/_zh-cn/tour/implicit-parameters.md b/_zh-cn/tour/implicit-parameters.md index 6e2c235baf..aa264c086d 100644 --- a/_zh-cn/tour/implicit-parameters.md +++ b/_zh-cn/tour/implicit-parameters.md @@ -22,7 +22,7 @@ Scala 将查找这些参数的位置分为两类: 在下面的例子中,我们定义了一个方法 `sum`,它使用 Monoid 类的 `add` 和 `unit` 方法计算一个列表中元素的总和。 请注意,隐式值不能是顶级值。 -```tut +```scala mdoc abstract class Monoid[A] { def add(x: A, y: A): A def unit: A diff --git a/_zh-cn/tour/inner-classes.md b/_zh-cn/tour/inner-classes.md index 499dd26b19..d8fede0742 100644 --- a/_zh-cn/tour/inner-classes.md +++ b/_zh-cn/tour/inner-classes.md @@ -15,7 +15,7 @@ previous-page: lower-type-bounds 为了说明差异,我们简单描述了一个图形数据类型的实现: -```tut +```scala mdoc class Graph { class Node { var connectedNodes: List[Node] = Nil @@ -35,7 +35,7 @@ class Graph { ``` 该程序将图形表示为节点列表 (`List[Node]`)。 每个节点都有一个用来存储与其相连的其他节点的列表 (`connectedNodes`)。 类 `Node` 是一个 _路径依赖类型_,因为它嵌套在类 `Graph` 中。 因此,`connectedNodes` 中存储的所有节点必须使用同一个 `Graph` 的实例对象的 `newNode` 方法来创建。 -```tut +```scala mdoc val graph1: Graph = new Graph val node1: graph1.Node = graph1.newNode val node2: graph1.Node = graph1.newNode @@ -48,7 +48,7 @@ node3.connectTo(node1) 如果我们现在有两个图形,Scala 的类型系统不允许我们将一个图形中定义的节点与另一个图形的节点混合,因为另一个图形的节点具有不同的类型。 下例是一个非法的程序: -``` +```scala mdoc:fail val graph1: Graph = new Graph val node1: graph1.Node = graph1.newNode val node2: graph1.Node = graph1.newNode @@ -59,7 +59,7 @@ node1.connectTo(node3) // illegal! ``` 类型 `graph1.Node` 与类型 `graph2.Node` 完全不同。 在 Java 中,上一个示例程序中的最后一行是正确的。 对于两个图形的节点,Java 将分配相同的类型 `Graph.Node`; 即 `Node` 以类 `Graph` 为前缀。 在Scala中也可以表示出这种类型,它写成了 `Graph#Node`。 如果我们希望能够连接不同图形的节点,我们必须通过以下方式更改图形类的初始实现的定义: -```tut +```scala mdoc:nest class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil @@ -77,4 +77,4 @@ class Graph { } } ``` - \ No newline at end of file + diff --git a/_zh-cn/tour/lower-type-bounds.md b/_zh-cn/tour/lower-type-bounds.md index 26c1bfba81..b511f52cf7 100644 --- a/_zh-cn/tour/lower-type-bounds.md +++ b/_zh-cn/tour/lower-type-bounds.md @@ -15,7 +15,7 @@ previous-page: upper-type-bounds 下面看一个适合用类型下界的例子: -```tut:fail +```scala mdoc:fail trait Node[+B] { def prepend(elem: B): Node[B] } @@ -37,7 +37,7 @@ case class Nil[+B]() extends Node[B] { 要解决这个问题,我们需要将方法 `prepend` 的参数 `elem` 的型变翻转。 我们通过引入一个新的类型参数 `U` 来实现这一点,该参数具有 `B` 作为类型下界。 -```tut +```scala mdoc trait Node[+B] { def prepend[U >: B](elem: U): Node[U] } @@ -54,7 +54,7 @@ case class Nil[+B]() extends Node[B] { ``` 现在我们像下面这么做: -```tut +```scala mdoc trait Bird case class AfricanSwallow() extends Bird case class EuropeanSwallow() extends Bird diff --git a/_zh-cn/tour/mixin-class-composition.md b/_zh-cn/tour/mixin-class-composition.md index 1875e0ec58..1b4c6bab36 100644 --- a/_zh-cn/tour/mixin-class-composition.md +++ b/_zh-cn/tour/mixin-class-composition.md @@ -13,7 +13,7 @@ previous-page: tuples 当某个特质被用于组合类时,被称为混入。 -```tut +```scala mdoc abstract class A { val message: String } @@ -34,7 +34,7 @@ println(d.loudMessage) // I'M AN INSTANCE OF CLASS B 现在,让我们看一个更有趣的例子,其中使用了抽象类: -```tut +```scala mdoc abstract class AbsIterator { type T def hasNext: Boolean @@ -46,7 +46,7 @@ abstract class AbsIterator { 接下来,我们将实现一个具体的类(所有的抽象成员`T`、`hasNext`和`next`都会被实现): -```tut +```scala mdoc class StringIterator(s: String) extends AbsIterator { type T = Char private var i = 0 @@ -63,7 +63,7 @@ class StringIterator(s: String) extends AbsIterator { 现在我们创建一个特质,也继承于`AbsIterator`。 -```tut +```scala mdoc trait RichIterator extends AbsIterator { def foreach(f: T => Unit): Unit = while (hasNext) f(next()) } @@ -73,7 +73,7 @@ trait RichIterator extends AbsIterator { 下面我们要把`StringIterator`和`RichIterator` 中的功能组合成一个类。 -```tut +```scala mdoc object StringIteratorTest extends App { class RichStringIter extends StringIterator("Scala") with RichIterator val richStringIter = new RichStringIter diff --git a/_zh-cn/tour/multiple-parameter-lists.md b/_zh-cn/tour/multiple-parameter-lists.md index 6237d1fc37..d0c16aebb1 100644 --- a/_zh-cn/tour/multiple-parameter-lists.md +++ b/_zh-cn/tour/multiple-parameter-lists.md @@ -15,7 +15,7 @@ previous-page: nested-functions 下面是一个例子,在Scala集合 `trait TraversableOnce` 定义了 `foldLeft` -``` +```scala mdoc:fail def foldLeft[B](z: B)(op: (B, A) => B): B ``` @@ -23,7 +23,7 @@ def foldLeft[B](z: B)(op: (B, A) => B): B 从初值0开始, 这里 `foldLeft` 将函数 `(m, n) => m + n` 依次应用到列表中的每一个元素和之前累积的值上。 -```tut +```scala mdoc val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val res = numbers.foldLeft(0)((m, n) => m + n) print(res) // 55 @@ -34,18 +34,18 @@ print(res) // 55 #### 单一的函数参数 在某些情况下存在单一的函数参数时,例如上述例子`foldLeft`中的`op`,多参数列表可以使得传递匿名函数作为参数的语法更为简洁。如果不使用多参数列表,代码可能像这样: -``` +```scala numbers.foldLeft(0, {(m: Int, n: Int) => m + n}) ``` 注意使用多参数列表时,我们还可以利用Scala的类型推断来让代码更加简洁(如下所示),而如果没有多参数列表,这是不可能的。 - -``` + +```scala mdoc numbers.foldLeft(0)(_ + _) ``` 像上述语句这样,我们可以给定多参数列表的一部分参数列表(如上述的`z`)来形成一个新的函数(partially applied function),达到复用的目的,如下所示: -```tut +```scala mdoc:nest val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val numberFunc = numbers.foldLeft(List[Int]())_ @@ -57,7 +57,7 @@ print(cubes.toString()) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000) ``` 最后,`foldLeft` 和 `foldRight` 可以按以下任意一种形式使用, -```tut +```scala mdoc:nest val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) numbers.foldLeft(0)((sum, item) => sum + item) // Generic Form @@ -71,7 +71,7 @@ numbers.foldRight(0)(_+_) // Curried Form #### 隐式(implicit)参数 如果要指定参数列表中的某些参数为隐式(implicit),应该使用多参数列表。例如: -``` +```scala def execute(arg: Int)(implicit ec: ExecutionContext) = ??? ``` diff --git a/_zh-cn/tour/named-arguments.md b/_zh-cn/tour/named-arguments.md index 16fa1f0e12..2a25884bec 100644 --- a/_zh-cn/tour/named-arguments.md +++ b/_zh-cn/tour/named-arguments.md @@ -13,7 +13,7 @@ previous-page: default-parameter-values 当调用方法时,实际参数可以通过其对应的形式参数的名称来标记: -```tut +```scala mdoc def printName(first: String, last: String): Unit = { println(first + " " + last) } @@ -24,7 +24,7 @@ printName(last = "Smith", first = "John") // Prints "John Smith" ``` 注意使用命名参数时,顺序是可以重新排列的。 但是,如果某些参数被命名了,而其他参数没有,则未命名的参数要按照其方法签名中的参数顺序放在前面。 -```tut:fail +```scala mdoc:fail printName(last = "Smith", "john") // error: positional after named argument ``` diff --git a/_zh-cn/tour/nested-functions.md b/_zh-cn/tour/nested-functions.md index 60d9f1c9ac..388c04503f 100644 --- a/_zh-cn/tour/nested-functions.md +++ b/_zh-cn/tour/nested-functions.md @@ -13,7 +13,7 @@ previous-page: higher-order-functions 在Scala中可以嵌套定义方法。例如以下对象提供了一个`factorial`方法来计算给定数值的阶乘: -```tut +```scala mdoc def factorial(x: Int): Int = { def fact(x: Int, accumulator: Int): Int = { if (x <= 1) accumulator diff --git a/_zh-cn/tour/operators.md b/_zh-cn/tour/operators.md index 18b5283eaa..5c415752fa 100644 --- a/_zh-cn/tour/operators.md +++ b/_zh-cn/tour/operators.md @@ -22,7 +22,7 @@ previous-page: type-inference ## 定义和使用运算符 你可以使用任何合法标识符作为运算符。 包括像 `add` 这样的名字或像 `+` 这样的符号。 -```tut +```scala mdoc case class Vec(x: Double, y: Double) { def +(that: Vec) = Vec(this.x + that.x, this.y + that.y) } @@ -36,7 +36,7 @@ vector3.y // 3.0 ``` 类 Vec 有一个方法 `+`,我们用它来使 `vector1` 和 `vector2` 相加。 使用圆括号,你可以使用易读的语法来构建复杂表达式。 这是 `MyBool` 类的定义,其中有方法 `and` 和 `or`: -```tut +```scala mdoc case class MyBool(x: Boolean) { def and(that: MyBool): MyBool = if (x) that else this def or(that: MyBool): MyBool = if (x) this else that @@ -46,7 +46,7 @@ case class MyBool(x: Boolean) { 现在可以使用 `and` 和 `or` 作为中缀运算符: -```tut +```scala mdoc def not(x: MyBool) = x.negate def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y) ``` diff --git a/_zh-cn/tour/packages-and-imports.md b/_zh-cn/tour/packages-and-imports.md index 412e1029b7..883c961345 100644 --- a/_zh-cn/tour/packages-and-imports.md +++ b/_zh-cn/tour/packages-and-imports.md @@ -68,7 +68,7 @@ import users.{UserPreferences => UPrefs} // 导入类并且设置别名 Scala 不同于 Java 的一点是 Scala 可以在任何地方使用导入: -```tut +```scala mdoc def sqrtplus1(x: Int) = { import scala.math.sqrt sqrt(x) + 1.0 diff --git a/_zh-cn/tour/pattern-matching.md b/_zh-cn/tour/pattern-matching.md index 0666957531..c340c48546 100644 --- a/_zh-cn/tour/pattern-matching.md +++ b/_zh-cn/tour/pattern-matching.md @@ -16,7 +16,7 @@ previous-page: case-classes ## 语法 一个模式匹配语句包括一个待匹配的值,`match`关键字,以及至少一个`case`语句。 -```tut +```scala mdoc import scala.util.Random val x: Int = Random.nextInt(10) @@ -31,7 +31,7 @@ x match { 上述代码中的`val x`是一个0到10之间的随机整数,将它放在`match`运算符的左侧对其进行模式匹配,`match`的右侧是包含4条`case`的表达式,其中最后一个`case _`表示匹配其余所有情况,在这里就是其他可能的整型值。 `match`表达式具有一个结果值 -```tut +```scala mdoc def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" @@ -46,7 +46,7 @@ matchTest(1) // one 案例类非常适合用于模式匹配。 -```tut +```scala mdoc abstract class Notification case class Email(sender: String, title: String, body: String) extends Notification @@ -113,7 +113,7 @@ println(showImportantNotification(importantSms, importantPeopleInfo)) ## 仅匹配类型 也可以仅匹配类型,如下所示: -```tut +```scala mdoc abstract class Device case class Phone(model: String) extends Device { def screenOff = "Turning screen off" @@ -133,7 +133,7 @@ def goIdle(device: Device) = device match { 特质(trait)和类(class)可以用`sealed`标记为密封的,这意味着其所有子类都必须与之定义在相同文件中,从而保证所有子类型都是已知的。 -```tut +```scala mdoc sealed abstract class Furniture case class Couch() extends Furniture case class Chair() extends Furniture diff --git a/_zh-cn/tour/polymorphic-methods.md b/_zh-cn/tour/polymorphic-methods.md index 2b1a102b96..8b195febc5 100644 --- a/_zh-cn/tour/polymorphic-methods.md +++ b/_zh-cn/tour/polymorphic-methods.md @@ -15,7 +15,7 @@ Scala 中的方法可以按类型和值进行参数化。 语法和泛型类类 看下面的例子: -```tut +```scala mdoc def listOfDuplicates[A](x: A, length: Int): List[A] = { if (length < 1) Nil diff --git a/_zh-cn/tour/regular-expression-patterns.md b/_zh-cn/tour/regular-expression-patterns.md index 856ce7de4c..9709c0ade8 100644 --- a/_zh-cn/tour/regular-expression-patterns.md +++ b/_zh-cn/tour/regular-expression-patterns.md @@ -14,7 +14,7 @@ previous-page: singleton-objects 正则表达式是用来找出数据中的指定模式(或缺少该模式)的字符串。`.r`方法可使任意字符串变成一个正则表达式。 -```tut +```scala mdoc import scala.util.matching.Regex val numberPattern: Regex = "[0-9]".r @@ -29,7 +29,7 @@ numberPattern.findFirstMatchIn("awesomepassword") match { 你还可以使用括号来同时匹配多组正则表达式。 -```tut +```scala mdoc import scala.util.matching.Regex val keyValPattern: Regex = "([0-9a-zA-Z-#() ]+): ([0-9a-zA-Z-#() ]+)".r diff --git a/_zh-cn/tour/self-types.md b/_zh-cn/tour/self-types.md index 061cb4e986..c30e900480 100644 --- a/_zh-cn/tour/self-types.md +++ b/_zh-cn/tour/self-types.md @@ -15,7 +15,7 @@ previous-page: compound-types 自类型是一种细化 `this` 或 `this` 别名之类型的方法。 语法看起来像普通函数语法,但是意义完全不一样。 要在特质中使用自类型,写一个标识符,跟上要混入的另一个特质,以及 `=>`(例如 `someIdentifier: SomeOtherTrait =>`)。 -```tut +```scala mdoc trait User { def username: String } diff --git a/_zh-cn/tour/singleton-objects.md b/_zh-cn/tour/singleton-objects.md index f970a7ed24..1177e92d49 100644 --- a/_zh-cn/tour/singleton-objects.md +++ b/_zh-cn/tour/singleton-objects.md @@ -19,7 +19,7 @@ previous-page: pattern-matching # 定义一个单例对象 一个单例对象是就是一个值。单例对象的定义方式很像类,但是使用关键字 `object`: -```tut +```scala mdoc object Box ``` @@ -76,7 +76,7 @@ circle1.area 这里的 `class Circle` 有一个成员 `area` 是和具体的实例化对象相关的,单例对象 `object Circle` 包含一个方法 `calculateArea` ,它在每一个实例化对象中都是可见的。 伴生对象也可以包含工厂方法: -```tut +```scala mdoc class Email(val username: String, val domainName: String) object Email { diff --git a/_zh-cn/tour/tour-of-scala.md b/_zh-cn/tour/tour-of-scala.md index 387eff8c14..df7288f109 100644 --- a/_zh-cn/tour/tour-of-scala.md +++ b/_zh-cn/tour/tour-of-scala.md @@ -58,4 +58,4 @@ Scala设计的目标是与流行的Java运行环境(JRE)进行良好的互 ## 尽享学习之乐 -请点击菜单上的[下一页](basics.html)继续阅读。 \ No newline at end of file +请点击菜单上的[下一页](basics.html)继续阅读。 diff --git a/_zh-cn/tour/traits.md b/_zh-cn/tour/traits.md index 7e37bf5d23..83b7a39633 100644 --- a/_zh-cn/tour/traits.md +++ b/_zh-cn/tour/traits.md @@ -20,12 +20,12 @@ prerequisite-knowledge: expressions, classes, generics, objects, companion-objec ## 定义一个特质 最简化的特质就是关键字trait+标识符: -```tut +```scala mdoc trait HairColor ``` 特征作为泛型类型和抽象方法非常有用。 -```tut +```scala mdoc trait Iterator[A] { def hasNext: Boolean def next(): A @@ -37,7 +37,7 @@ trait Iterator[A] { ## 使用特质 使用 `extends` 关键字来扩展特征。然后使用 `override` 关键字来实现trait里面的任何抽象成员: -```tut +```scala mdoc:nest trait Iterator[A] { def hasNext: Boolean def next(): A @@ -64,7 +64,7 @@ iterator.next() // returns 1 ## 子类型 凡是需要特质的地方,都可以由该特质的子类型来替换。 -```tut +```scala mdoc import scala.collection.mutable.ArrayBuffer trait Pet { diff --git a/_zh-cn/tour/tuples.md b/_zh-cn/tour/tuples.md index 97f083a98e..871c70c3b5 100644 --- a/_zh-cn/tour/tuples.md +++ b/_zh-cn/tour/tuples.md @@ -19,7 +19,7 @@ topics: tuples 元组可以创建如下: -```tut +```scala mdoc val ingredient = ("Sugar" , 25):Tuple2[String, Int] ``` 这将创建一个包含一个 String 元素和一个 Int 元素的元组。 @@ -34,7 +34,7 @@ Scala 中的元组包含一系列类:Tuple2,Tuple3等,直到 Tuple22。 使用下划线语法来访问元组中的元素。 'tuple._n' 取出了第 n 个元素(假设有足够多元素)。 -```tut +```scala mdoc println(ingredient._1) // Sugar println(ingredient._2) // 25 @@ -44,7 +44,7 @@ println(ingredient._2) // 25 Scala 元组也支持解构。 -```tut +```scala mdoc val (name, quantity) = ingredient println(name) // Sugar @@ -54,7 +54,7 @@ println(quantity) // 25 元组解构也可用于模式匹配。 -```tut +```scala mdoc val planetDistanceFromSun = List(("Mercury", 57.9), ("Venus", 108.2), ("Earth", 149.6 ), ("Mars", 227.9), ("Jupiter", 778.3)) planetDistanceFromSun.foreach{ tuple => { @@ -78,7 +78,7 @@ planetDistanceFromSun.foreach{ tuple => { 或者,在 'for' 表达式中。 -```tut +```scala mdoc val numPairs = List((2, 5), (3, -7), (20, 56)) for ((a, b) <- numPairs) { diff --git a/_zh-cn/tour/type-inference.md b/_zh-cn/tour/type-inference.md index e3dd33a0c8..3b50faf3a4 100644 --- a/_zh-cn/tour/type-inference.md +++ b/_zh-cn/tour/type-inference.md @@ -15,19 +15,19 @@ Scala 编译器通常可以推断出表达式的类型,因此你不必显式 ## 省略类型 -```tut +```scala mdoc val businessName = "Montreux Jazz Café" ``` 编译器可以发现 `businessName` 是 String 类型。 它的工作原理和方法类似: -```tut +```scala mdoc def squareOf(x: Int) = x * x ``` 编译器可以推断出方法的返回类型为 `Int`,因此不需要明确地声明返回类型。 对于递归方法,编译器无法推断出结果类型。 下面这个程序就是由于这个原因而编译失败: -```tut:fail +```scala mdoc:fail def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) ``` @@ -35,7 +35,7 @@ def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) 看下面两个例子: -```tut +```scala mdoc case class MyPair[A, B](x: A, y: B) val p = MyPair(1, "scala") // type: MyPair[Int, String] @@ -49,7 +49,7 @@ val q = id(1) // type: Int 编译器从不推断方法形式参数的类型。 但是,在某些情况下,当函数作为参数传递时,编译器可以推断出匿名函数形式参数的类型。 -```tut +```scala mdoc Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) ``` @@ -61,13 +61,13 @@ Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) 此外,类型推断有时会推断出太具体的类型。 假设我们这么写: -```tut +```scala var obj = null ``` 我们就不能进行重新赋值: -```tut:fail +```scala mdoc:fail obj = new AnyRef ``` diff --git a/_zh-cn/tour/unified-types.md b/_zh-cn/tour/unified-types.md index 47e9db8f3f..b3d9055168 100644 --- a/_zh-cn/tour/unified-types.md +++ b/_zh-cn/tour/unified-types.md @@ -27,7 +27,7 @@ prerequisite-knowledge: classes, basics 这里有一个例子,说明了字符串、整型、布尔值和函数都是对象,这一点和其他对象一样: -```tut +```scala mdoc val list: List[Any] = List( "a string", 732, // an integer @@ -57,7 +57,7 @@ true 例如: -```tut +```scala mdoc val x: Long = 987654321 val y: Float = x // 9.8765434E8 (note that some precision is lost in this case) diff --git a/_zh-cn/tour/upper-type-bounds.md b/_zh-cn/tour/upper-type-bounds.md index 6baf50b6ab..917bc3e2e4 100644 --- a/_zh-cn/tour/upper-type-bounds.md +++ b/_zh-cn/tour/upper-type-bounds.md @@ -13,7 +13,7 @@ previous-page: variances 在Scala中,[类型参数](generic-classes.html)和[抽象类型](abstract-type-members.html)都可以有一个类型边界约束。这种类型边界在限制类型变量实际取值的同时还能展露类型成员的更多信息。比如像`T <: A`这样声明的类型上界表示类型变量`T`应该是类型`A`的子类。下面的例子展示了类`PetContainer`的一个类型参数的类型上界。 -```tut +```scala mdoc abstract class Animal { def name: String } @@ -40,7 +40,7 @@ val dogContainer = new PetContainer[Dog](new Dog) val catContainer = new PetContainer[Cat](new Cat) ``` -```tut:fail +```scala mdoc:fail // this would not compile val lionContainer = new PetContainer[Lion](new Lion) ``` diff --git a/_zh-cn/tour/variances.md b/_zh-cn/tour/variances.md index 257c1a78d6..ecd5249a35 100644 --- a/_zh-cn/tour/variances.md +++ b/_zh-cn/tour/variances.md @@ -13,7 +13,7 @@ previous-page: generic-classes 型变是复杂类型的子类型关系与其组件类型的子类型关系的相关性。 Scala支持 [泛型类](generic-classes.html) 的类型参数的型变注释,允许它们是协变的,逆变的,或在没有使用注释的情况下是不变的。 在类型系统中使用型变允许我们在复杂类型之间建立直观的连接,而缺乏型变则会限制类抽象的重用性。 -```tut +```scala mdoc class Foo[+A] // A covariant class class Bar[-A] // A contravariant class class Baz[A] // An invariant class @@ -25,7 +25,7 @@ class Baz[A] // An invariant class 考虑以下简单的类结构: -```tut +```scala mdoc abstract class Animal { def name: String } @@ -37,7 +37,7 @@ case class Dog(name: String) extends Animal 在下例中,方法 `printAnimalNames` 将接受动物列表作为参数,并且逐行打印出它们的名称。 如果 `List[A]` 不是协变的,最后两个方法调用将不能编译,这将严重限制 `printAnimalNames` 方法的适用性。 -```tut +```scala mdoc object CovarianceTest extends App { def printAnimalNames(animals: List[Animal]): Unit = { animals.foreach { animal => @@ -64,7 +64,7 @@ object CovarianceTest extends App { 考虑在下例中使用上面定义的类 `Cat`,`Dog` 和 `Animal` : -```tut +```scala mdoc abstract class Printer[-A] { def print(value: A): Unit } @@ -72,7 +72,7 @@ abstract class Printer[-A] { 这里 `Printer[A]` 是一个简单的类,用来打印出某种类型的 `A`。 让我们定义一些特定的子类: -```tut +```scala mdoc class AnimalPrinter extends Printer[Animal] { def print(animal: Animal): Unit = println("The animal's name is: " + animal.name) @@ -86,7 +86,7 @@ class CatPrinter extends Printer[Cat] { 如果 `Printer[Cat]` 知道如何在控制台打印出任意 `Cat`,并且 `Printer[Animal]` 知道如何在控制台打印出任意 `Animal`,那么 `Printer[Animal]` 也应该知道如何打印出 `Cat` 就是合理的。 反向关系不适用,因为 `Printer[Cat]` 并不知道如何在控制台打印出任意 `Animal`。 因此,如果我们愿意,我们应该能够用 `Printer[Animal]` 替换 `Printer[Cat]`,而使 `Printer[A]` 逆变允许我们做到这一点。 -```tut +```scala mdoc object ContravarianceTest extends App { val myCat: Cat = Cat("Boots") @@ -113,7 +113,7 @@ The animal's name is: Boots 默认情况下,Scala中的泛型类是不变的。 这意味着它们既不是协变的也不是逆变的。 在下例中,类 `Container` 是不变的。 `Container[Cat]` _不是_ `Container[Animal]`,反之亦然。 -```tut +```scala mdoc class Container[A](value: A) { private var _value: A = value def getValue: A = _value @@ -140,7 +140,7 @@ val cat: Cat = catContainer.getValue // 糟糕,我们最终会将一只狗作 假设前面使用过的类似 `Cat`,`Dog`,`Animal` 的继承关系,加上以下内容: -```tut +```scala mdoc abstract class SmallAnimal extends Animal case class Mouse(name: String) extends SmallAnimal ``` diff --git a/contribute.md b/contribute.md index 7957f89055..faeb5b6ac4 100644 --- a/contribute.md +++ b/contribute.md @@ -144,3 +144,52 @@ For now, cheatsheets are assumed to be in the form of tables. To contribute a ch by: YOUR NAME about: SOME TEXT ABOUT THE CHEAT SHEET. --- + +### Code blocks + +The site build process uses [mdoc](https://scalameta.org/mdoc/) to typecheck +code snippets in markdown. This is a great way to ensure the code snippets that +you're including typecheck and are valid. Here are a few quick types to get +started. + +To get started, you can simply add `mdoc` behind `scala` when you are creating a +code block. The `mdoc` modifier here will make sure that `mdoc` runs the code +snippet and ensures that it's valid. + + ```scala mdoc + val a = 1 + ``` +If you have a snippet that you expect to fail, you can also account for this by +using `mdoc:fail` for a compile error `mdoc:crash` for a runtime-error. + + ```scala mdoc:fail + val b: String = 3 // won't compile + ``` +Keep in mind that a single file is all compiled as a single unit, so you can't +redefine a variable that was defined above in another code snippet. _However_ +there are a couple ways to get around this. Firstly, you can use the `mdoc:nest` +modifier with will wrap the snippet in a `scala.Predef.locally{...}`. This will +essentially "hide" the snippet from the others. Another way around this is to +use the `mdoc:reset` modifier, which _resets_ and forgets about everything up +above. Here is an example using the various modifiers. + + ```scala mdoc + import java.time.Instant + + def now() = Instant.now() + object Foo {} + ``` + + ```scala mdoc:nest + case class Foo(a: Int) // conflicts with Foo above, but it's nested so it's fine + ``` + + ```scala mdoc + val a = s"The time is ${now()}" // still have access to the now method from above + ``` + ```scala mdoc:reset + case class Foo(a: String) // forget the previous Foo's and start fresh + ``` + ```scala mdoc + val myFoo = Foo("hi") // now we only have access to the last Foo + ``` diff --git a/scripts/ci.sh b/scripts/ci.sh index 5547cad2df..99949e207e 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -5,8 +5,8 @@ set -eux bundle install -./scripts/run-tut.sh -rm -r tut-tmp +./scripts/run-mdoc.sh +rm -r /tmp/mdoc-out/ bundle exec jekyll build # Checking for docs.scala-lang/blob/master leads to a chicken and egg problem because of the edit links of new pages. diff --git a/scripts/run-mdoc.sh b/scripts/run-mdoc.sh new file mode 100755 index 0000000000..e795f9b4aa --- /dev/null +++ b/scripts/run-mdoc.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -eux + +coursier launch org.scalameta:mdoc_2.12:2.2.13 -- \ + --in . \ + --out /tmp/mdoc-out/ \ + --classpath $(coursier fetch -p com.chuusai:shapeless_2.12:2.3.3) \ + --scalac-options "-Xfatal-warnings -feature" \ + --no-link-hygiene \ + --include '**.md' + +exit 0 diff --git a/scripts/run-tut.sh b/scripts/run-tut.sh deleted file mode 100755 index eff6ffb5ce..0000000000 --- a/scripts/run-tut.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -set -eux - -# black-list _overviews/contributors/index.md because it embeds a Markdown snippet which embeds Scala code that does not compile -mv _overviews/contributors/index.md /tmp/_overviews_contributors_index.md - -coursier launch -r "https://dl.bintray.com/tpolecat/maven/" org.tpolecat:tut-core_2.12:0.6.13 -- . tut-tmp '.*\.md$' -classpath $(coursier fetch -p com.chuusai:shapeless_2.12:2.3.3) -Xfatal-warnings -feature - -# restore _overviews/contributors/index.md file -mv /tmp/_overviews_contributors_index.md _overviews/contributors/index.md - -exit 0