From f658ce8685b9a0eef0ae6e75c5cd91f6cc75f566 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 17:53:09 +0200 Subject: [PATCH 01/16] Update run-mdoc.sh try upgrade mdoc for scala 2.13 --- scripts/run-mdoc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/run-mdoc.sh b/scripts/run-mdoc.sh index 97593abd20..32e7d23d2c 100755 --- a/scripts/run-mdoc.sh +++ b/scripts/run-mdoc.sh @@ -1,10 +1,10 @@ #!/bin/bash set -eux -cs launch org.scalameta:mdoc_2.12:2.2.13 -- \ +cs launch org.scalameta:mdoc_2.13:2.3.3 -- \ --in . \ --out /tmp/mdoc-out/ \ - --classpath $(cs fetch -p com.chuusai:shapeless_2.12:2.3.3) \ + --classpath $(cs fetch -p com.chuusai:shapeless_2.13:2.3.10) \ --scalac-options "-Xfatal-warnings -feature" \ --no-link-hygiene \ --include '**.md' From 9e940ee6e73e5521525b3cd5a0d8e15f1f659415 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 18:00:59 +0200 Subject: [PATCH 02/16] use more string interpolators --- _ba/tour/basics.md | 22 +++++++++++----------- _es/tour/basics.md | 12 ++++++------ _ko/tour/basics.md | 8 ++++---- _ru/tour/basics.md | 16 ++++++++-------- _th/tour/basics.md | 10 +++++----- _zh-cn/tour/basics.md | 8 ++++---- 6 files changed, 38 insertions(+), 38 deletions(-) diff --git a/_ba/tour/basics.md b/_ba/tour/basics.md index 3112cb7850..97956e6149 100644 --- a/_ba/tour/basics.md +++ b/_ba/tour/basics.md @@ -46,7 +46,7 @@ val x = 1 + 1 println(x) // 2 ``` -Imenovani rezultati, kao `x` ovdje, nazivaju se vrijednostima. +Imenovani rezultati, kao `x` ovdje, nazivaju se vrijednostima. Referenciranje vrijednosti ne okida njeno ponovno izračunavanje. Vrijednosti se ne mogu mijenjati. @@ -61,7 +61,7 @@ Tipovi vrijednosti mogu biti (automatski) zaključeni, ali možete i eksplicitno val x: Int = 1 + 1 ``` -Primijetite da deklaracija tipa `Int` dolazi nakon identifikatora `x`. Također morate dodati i `:`. +Primijetite da deklaracija tipa `Int` dolazi nakon identifikatora `x`. Također morate dodati i `:`. ### Varijable @@ -177,9 +177,9 @@ class Greeter(prefix: String, suffix: String) { println(prefix + name + suffix) } ``` -Povratni tip metode `greet` je `Unit`, koji kaže da metoda ne vraća ništa značajno. -Koristi se slično kao `void` u Javi ili C-u. -(Razlika je u tome što svaki Scalin izraz mora imati neku vrijednost, postoji singlton vrijednost tipa `Unit`, piše se `()`. +Povratni tip metode `greet` je `Unit`, koji kaže da metoda ne vraća ništa značajno. +Koristi se slično kao `void` u Javi ili C-u. +(Razlika je u tome što svaki Scalin izraz mora imati neku vrijednost, postoji singlton vrijednost tipa `Unit`, piše se `()`. Ne prenosi nikakvu korisnu informaciju.) Instancu klase možete kreirati pomoću ključne riječi `new`. @@ -193,7 +193,7 @@ Detaljniji pregled klasa biće dat [kasnije](classes.html). ## Case klase -Scala ima poseban tip klase koji se zove "case" klasa. +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. ```scala mdoc @@ -212,15 +212,15 @@ I porede se po vrijednosti. ```scala mdoc if (point == anotherPoint) { - println(point + " and " + anotherPoint + " are the same.") + println(s"$point and $anotherPoint are the same.") } else { - println(point + " and " + anotherPoint + " are different.") + println(s"$point and $anotherPoint are different.") } // Point(1,2) i Point(1,2) su iste. if (point == yetAnotherPoint) { - println(point + " and " + yetAnotherPoint + " are the same.") + println(s"$point and $yetAnotherPoint are the same.") } else { - println(point + " and " + yetAnotherPoint + " are different.") + println(s"$point and $yetAnotherPoint are different.") } // Point(1,2) su Point(2,2) različite. ``` @@ -299,7 +299,7 @@ Trejtove ćemo pokriti u dubinu [kasnije](traits.html). ## Glavna metoda -Glavna metoda je ulazna tačka programa. +Glavna metoda je ulazna tačka programa. Java Virtuelna Mašina traži da se glavna metoda zove `main` i da prima jedan argument, niz stringova. Koristeći objekt, možete definisati glavnu metodu ovako: diff --git a/_es/tour/basics.md b/_es/tour/basics.md index dcba773802..cbbe76a021 100644 --- a/_es/tour/basics.md +++ b/_es/tour/basics.md @@ -129,7 +129,7 @@ println(getTheAnswer()) // 42 ## Métodos -Los métodos se parecen y comportan casi como a las funciones, pero se diferencian en dos aspectos clave: +Los métodos se parecen y comportan casi como a las funciones, pero se diferencian en dos aspectos clave: 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. @@ -200,7 +200,7 @@ Una case class se define con las palabras reservadas `case class`: case class Point(x: Int, y: Int) ``` -Se puede crear una instancia de una `case class`, sin usar la palabra reservada `new`. +Se puede crear una instancia de una `case class`, sin usar la palabra reservada `new`. ```scala mdoc val point = Point(1, 2) @@ -212,15 +212,15 @@ Y son comparadas por valor. ```scala mdoc if (point == anotherPoint) { - println(point + " and " + anotherPoint + " are the same.") + println(s"$point and $anotherPoint are the same.") } else { - println(point + " and " + anotherPoint + " are different.") + println(s"$point and $anotherPoint are different.") } // Point(1,2) and Point(1,2) are the same. if (point == yetAnotherPoint) { - println(point + " and " + yetAnotherPoint + " are the same.") + println(s"$point and $yetAnotherPoint are the same.") } else { - println(point + " and " + yetAnotherPoint + " are different.") + println(s"$point and $yetAnotherPoint are different.") } // Point(1,2) and Point(2,2) are different. ``` diff --git a/_ko/tour/basics.md b/_ko/tour/basics.md index b8dd2a3259..033592c302 100644 --- a/_ko/tour/basics.md +++ b/_ko/tour/basics.md @@ -210,15 +210,15 @@ val yetAnotherPoint = Point(2, 2) ```scala mdoc if (point == anotherPoint) { - println(point + " and " + anotherPoint + " are the same.") + println(s"$point and $anotherPoint are the same.") } else { - println(point + " and " + anotherPoint + " are different.") + println(s"$point and $anotherPoint are different.") } // Point(1,2) and Point(1,2) are the same. if (point == yetAnotherPoint) { - println(point + " and " + yetAnotherPoint + " are the same.") + println(s"$point and $yetAnotherPoint are the same.") } else { - println(point + " and " + yetAnotherPoint + " are different.") + println(s"$point and $yetAnotherPoint are different.") } // Point(1,2) and Point(2,2) are different. ``` diff --git a/_ru/tour/basics.md b/_ru/tour/basics.md index b3ceaaae51..8af52f18fe 100644 --- a/_ru/tour/basics.md +++ b/_ru/tour/basics.md @@ -20,7 +20,7 @@ previous-page: tour-of-scala Это простой способ поэкспериментировать со Scala кодом без всяких настроек. -Большинство примеров кода в этой документации также интегрированы с Scastie, +Большинство примеров кода в этой документации также интегрированы с Scastie, поэтому вы можете поэкспериментировать с ними, просто нажав кнопку Run. ## Выражения @@ -47,7 +47,7 @@ val x = 1 + 1 println(x) // 2 ``` -Названные результаты, такие как `x` в примере, называются значениями. +Названные результаты, такие как `x` в примере, называются значениями. Вызов значения не приводит к его повторному вычислению. Значения не изменяемы и не могут быть переназначены. @@ -62,7 +62,7 @@ x = 3 // Не компилируется. val x: Int = 1 + 1 ``` -Обратите внимание, что объявление типа `Int` происходит после идентификатора `x`, следующим за `:`. +Обратите внимание, что объявление типа `Int` происходит после идентификатора `x`, следующим за `:`. ### Переменные @@ -209,15 +209,15 @@ val yetAnotherPoint = Point(2, 2) ```scala mdoc if (point == anotherPoint) { - println(point + " and " + anotherPoint + " are the same.") + println(s"$point and $anotherPoint are the same.") } else { - println(point + " and " + anotherPoint + " are different.") + println(s"$point and $anotherPoint are different.") } // Point(1,2) и Point(1,2) одни и те же. if (point == yetAnotherPoint) { - println(point + " and " + yetAnotherPoint + " are the same.") + println(s"$point and $yetAnotherPoint are the same.") } else { - println(point + " and " + yetAnotherPoint + " are different.") + println(s"$point and $yetAnotherPoint are different.") } // Point(1,2) и Point(2,2) разные. ``` @@ -295,7 +295,7 @@ customGreeter.greet("Scala developer") // How are you, Scala developer? ## Главный метод -Главный метод является отправной точкой в программе. +Главный метод является отправной точкой в программе. Для Виртуальной Машины Java требуется, чтобы главный метод назывался `main` и принимал один аргумент, массив строк. Используя объект, можно задать главный метод следующим образом: diff --git a/_th/tour/basics.md b/_th/tour/basics.md index c2e4653d1a..29f05e62fd 100644 --- a/_th/tour/basics.md +++ b/_th/tour/basics.md @@ -210,15 +210,15 @@ val yetAnotherPoint = Point(2, 2) ```scala mdoc if (point == anotherPoint) { - println(point + " and " + anotherPoint + " are the same.") + println(s"$point and $anotherPoint are the same.") } else { - println(point + " and " + anotherPoint + " are different.") + println(s"$point and $anotherPoint are different.") } // Point(1,2) and Point(1,2) are the same. if (point == yetAnotherPoint) { - println(point + " and " + yetAnotherPoint + " are the same.") + println(s"$point and $yetAnotherPoint are the same.") } else { - println(point + " and " + yetAnotherPoint + " are different.") + println(s"$point and $yetAnotherPoint are different.") } // Point(1,2) and Point(2,2) are different. ``` @@ -296,7 +296,7 @@ customGreeter.greet("Scala developer") // How are you, Scala developer? ## Main Method -main method เป็น entry point หรือจุดเริ่มต้นของโปรแกรม ใน ​Java Virtual Machine +main method เป็น entry point หรือจุดเริ่มต้นของโปรแกรม ใน ​Java Virtual Machine ต้องการ main method ชื่อว่า `main` และสามารถรับ argument ที่เป็น array ของ string ใช้ object เราสามารถประกาศ main method ได้ดังนี้: diff --git a/_zh-cn/tour/basics.md b/_zh-cn/tour/basics.md index 5312c39a2c..6c9d42321a 100644 --- a/_zh-cn/tour/basics.md +++ b/_zh-cn/tour/basics.md @@ -209,15 +209,15 @@ val yetAnotherPoint = Point(2, 2) ```scala mdoc if (point == anotherPoint) { - println(point + " and " + anotherPoint + " are the same.") + println(s"$point and $anotherPoint are the same.") } else { - println(point + " and " + anotherPoint + " are different.") + println(s"$point and $anotherPoint are different.") } // Point(1,2) and Point(1,2) are the same. if (point == yetAnotherPoint) { - println(point + " and " + yetAnotherPoint + " are the same.") + println(s"$point and $yetAnotherPoint are the same.") } else { - println(point + " and " + yetAnotherPoint + " are different.") + println(s"$point and $yetAnotherPoint are different.") } // Point(1,2) and Point(2,2) are different. ``` From 7b3b70f349884a7c1d580a7753a0c325146340cb Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 18:03:52 +0200 Subject: [PATCH 03/16] explicit apply empty param list --- _ba/tour/extractor-objects.md | 10 +++++----- _fr/tour/extractor-objects.md | 8 ++++---- _ja/tour/extractor-objects.md | 2 +- _ru/tour/extractor-objects.md | 4 ++-- _tour/extractor-objects.md | 2 +- _zh-cn/tour/extractor-objects.md | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/_ba/tour/extractor-objects.md b/_ba/tour/extractor-objects.md index ac948e255d..0d0618aa00 100644 --- a/_ba/tour/extractor-objects.md +++ b/_ba/tour/extractor-objects.md @@ -11,7 +11,7 @@ previous-page: regular-expression-patterns --- 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. +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. ```scala mdoc @@ -19,7 +19,7 @@ import scala.util.Random object CustomerID { - def apply(name: String) = s"$name--${Random.nextLong}" + def apply(name: String) = s"$name--${Random.nextLong()}" def unapply(customerID: String): Option[String] = { val name = customerID.split("--").head @@ -34,9 +34,9 @@ customer1ID match { } ``` -Metoda `apply` kreira `CustomerID` string od argumenta `name`. -Metoda `unapply` radi suprotno da dobije `name` nazad. -Kada pozovemo `CustomerID("Sukyoung")`, to je skraćena sintaksa za `CustomerID.apply("Sukyoung")`. +Metoda `apply` kreira `CustomerID` string od argumenta `name`. +Metoda `unapply` radi suprotno da dobije `name` nazad. +Kada pozovemo `CustomerID("Sukyoung")`, to je skraćena sintaksa za `CustomerID.apply("Sukyoung")`. Kada pozovemo `case CustomerID(name) => customer1ID`, ustvari pozivamo `unapply` metodu. Metoda `unapply` se može koristiti i za dodjelu vrijednosti. diff --git a/_fr/tour/extractor-objects.md b/_fr/tour/extractor-objects.md index 9ffc529a58..1f864b7f39 100644 --- a/_fr/tour/extractor-objects.md +++ b/_fr/tour/extractor-objects.md @@ -12,13 +12,13 @@ previous-page: regular-expression-patterns --- Un objet extracteur est un objet avec une méthode `unapply`. Tandis que la méthode `apply` ressemble à un constructeur qui prend des arguments et crée un objet, `unapply` prend un object et essaye de retourner ses arguments. Il est utilisé le plus souvent en filtrage par motif (*pattern matching*) ou avec les fonctions partielles. - + ```scala mdoc import scala.util.Random object CustomerID { - def apply(name: String) = s"$name--${Random.nextLong}" + def apply(name: String) = s"$name--${Random.nextLong()}" def unapply(customerID: String): Option[String] = { val stringArray: Array[String] = customerID.split("--") @@ -35,7 +35,7 @@ customer1ID match { La méthode `apply` crée une chaîne de caractères `CustomerID` depuis `name`. La méthode `unapply` fait l'inverse pour retrouver le `name`. Lorsqu'on appelle `CustomerID("Sukyoung")`, c'est un raccourci pour `CustomerID.apply("Sukyoung")`. Lorsqu'on appelle `case CustomerID(name) => println(name)`, on appelle la méthode `unapply` avec `CustomerID.unapply(customer1ID)`. -Sachant qu'une définition de valeur peut utiliser une décomposition pour introduire une nouvelle variable, un extracteur peut être utilisé pour initialiser la variable, avec la méthode `unapply` pour fournir la valeur. +Sachant qu'une définition de valeur peut utiliser une décomposition pour introduire une nouvelle variable, un extracteur peut être utilisé pour initialiser la variable, avec la méthode `unapply` pour fournir la valeur. ```scala mdoc val customer2ID = CustomerID("Nico") @@ -63,4 +63,4 @@ Le type de retour de `unapply` doit être choisi comme suit : Parfois, le nombre de valeurs à extraire n'est pas fixe et on souhaiterait retourner un nombre arbitraire de valeurs, en fonction des données d'entrée. Pour ce cas, vous pouvez définir des extracteurs avec la méthode `unapplySeq` qui retourne un `Option[Seq[T]]`. Un exemple commun d'utilisation est la déconstruction d'une liste en utilisant `case List(x, y, z) =>`. Un autre est la décomposition d'une `String` en utilisant une expression régulière `Regex`, comme `case r(name, remainingFields @ _*) =>`. -Traduit par Antoine Pointeau. \ No newline at end of file +Traduit par Antoine Pointeau. diff --git a/_ja/tour/extractor-objects.md b/_ja/tour/extractor-objects.md index 6dac1d2209..03efef77e3 100644 --- a/_ja/tour/extractor-objects.md +++ b/_ja/tour/extractor-objects.md @@ -17,7 +17,7 @@ import scala.util.Random object CustomerID { - def apply(name: String) = s"$name--${Random.nextLong}" + def apply(name: String) = s"$name--${Random.nextLong()}" def unapply(customerID: String): Option[String] = { val stringArray: Array[String] = customerID.split("--") diff --git a/_ru/tour/extractor-objects.md b/_ru/tour/extractor-objects.md index 8d86b454ac..5be38a2c2f 100644 --- a/_ru/tour/extractor-objects.md +++ b/_ru/tour/extractor-objects.md @@ -15,7 +15,7 @@ import scala.util.Random object CustomerID { - def apply(name: String) = s"$name--${Random.nextLong}" + def apply(name: String) = s"$name--${Random.nextLong()}" def unapply(customerID: String): Option[String] = { val stringArray: Array[String] = customerID.split("--") @@ -57,4 +57,4 @@ val CustomerID(name3) = "-asdfasdfasdf" * Если в результате найдено одно значение типа `T`, то возвращается `Option[T]`. * Если вы хотите получить несколько значений `T1,..., Tn`, то ответ необходимо группировать в дополнительный кортеж `Option[(T1,..., Tn)]`. -Иногда количество извлекаемых значений не является фиксированным. Если в зависимости от входа мы хотим вернуть произвольное количество значений, то для этого случая мы можем определить экстрактор методом `unapplySeq`, который возвращает `Option[Seq[T]]`. Характерным примером такого подхода является разложение `List` с помощью `case List(x, y, z) =>` и разложение `String` с помощью регулярного выражения `Regex`, такого как `case r(name, remainingFields @ _*) =>`. +Иногда количество извлекаемых значений не является фиксированным. Если в зависимости от входа мы хотим вернуть произвольное количество значений, то для этого случая мы можем определить экстрактор методом `unapplySeq`, который возвращает `Option[Seq[T]]`. Характерным примером такого подхода является разложение `List` с помощью `case List(x, y, z) =>` и разложение `String` с помощью регулярного выражения `Regex`, такого как `case r(name, remainingFields @ _*) =>`. diff --git a/_tour/extractor-objects.md b/_tour/extractor-objects.md index b7e08ed708..0ee215f55e 100644 --- a/_tour/extractor-objects.md +++ b/_tour/extractor-objects.md @@ -17,7 +17,7 @@ import scala.util.Random object CustomerID { - def apply(name: String) = s"$name--${Random.nextLong}" + def apply(name: String) = s"$name--${Random.nextLong()}" def unapply(customerID: String): Option[String] = { val stringArray: Array[String] = customerID.split("--") diff --git a/_zh-cn/tour/extractor-objects.md b/_zh-cn/tour/extractor-objects.md index d6d75aaad8..c74d946482 100644 --- a/_zh-cn/tour/extractor-objects.md +++ b/_zh-cn/tour/extractor-objects.md @@ -18,7 +18,7 @@ import scala.util.Random object CustomerID { - def apply(name: String) = s"$name--${Random.nextLong}" + def apply(name: String) = s"$name--${Random.nextLong()}" def unapply(customerID: String): Option[String] = { val stringArray: Array[String] = customerID.split("--") From ea704602f281ba0d16cafc949ba324c2f4a111b1 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 18:05:46 +0200 Subject: [PATCH 04/16] remove redundant override --- _ba/tour/higher-order-functions.md | 6 +++--- _pt-br/tour/higher-order-functions.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/_ba/tour/higher-order-functions.md b/_ba/tour/higher-order-functions.md index 8ddead84a5..56f1c1807a 100644 --- a/_ba/tour/higher-order-functions.md +++ b/_ba/tour/higher-order-functions.md @@ -21,19 +21,19 @@ def apply(f: Int => String, v: Int) = f(v) _Napomena: metode se automatski pretvaraju u funkcije ako to kontekst zahtijeva._ Ovo je još jedan primjer: - + ```scala mdoc class Decorator(left: String, right: String) { def layout[A](x: A) = left + x.toString() + right } object FunTest extends App { - override def apply(f: Int => String, v: Int) = f(v) + def apply(f: Int => String, v: Int) = f(v) val decorator = new Decorator("[", "]") println(apply(decorator.layout, 7)) } ``` - + Izvršavanjem se dobije izlaz: ``` diff --git a/_pt-br/tour/higher-order-functions.md b/_pt-br/tour/higher-order-functions.md index f71baf9e67..d2549f72db 100644 --- a/_pt-br/tour/higher-order-functions.md +++ b/_pt-br/tour/higher-order-functions.md @@ -25,7 +25,7 @@ class Decorator(left: String, right: String) { } object FunTest extends App { - override def apply(f: Int => String, v: Int) = f(v) + def apply(f: Int => String, v: Int) = f(v) val decorator = new Decorator("[", "]") println(apply(decorator.layout, 7)) } From 46ac178b60808004a9e4f00ffa4dedbef7cabde8 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 18:11:36 +0200 Subject: [PATCH 05/16] remove some procedure syntax --- _ba/tour/inner-classes.md | 12 ++++++------ _es/tour/inner-classes.md | 2 +- _ja/tour/inner-classes.md | 2 +- _ko/tour/inner-classes.md | 22 +++++++++++----------- _pl/tour/inner-classes.md | 22 +++++++++++----------- _pt-br/tour/inner-classes.md | 10 +++++----- _ru/tour/inner-classes.md | 4 ++-- _zh-cn/tour/inner-classes.md | 3 +-- 8 files changed, 38 insertions(+), 39 deletions(-) diff --git a/_ba/tour/inner-classes.md b/_ba/tour/inner-classes.md index 10eac53bfb..dade40c827 100644 --- a/_ba/tour/inner-classes.md +++ b/_ba/tour/inner-classes.md @@ -21,7 +21,7 @@ Radi ilustracije razlike, prikazaćemo implementaciju klase grafa: class Graph { class Node { var connectedNodes: List[Node] = Nil - def connectTo(node: Node) { + def connectTo(node: Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } @@ -35,7 +35,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`. @@ -47,13 +47,13 @@ val node3: graph1.Node = graph1.newNode node1.connectTo(node2) node3.connectTo(node1) ``` - + Eksplicitno smo deklarisali tip `node1`, `node2`, i `node3` kao `graph1.Node` zbog jasnosti ali ga je kompajler mogao sam zaključiti. Pošto kada pozivamo `graph1.newNode` koja poziva `new Node`, metoda koristi instancu `Node` specifičnu instanci `graph1`. Da imamo dva grafa, sistem tipova Scale ne dozvoljava miješanje čvorova definisanih u različitim grafovima, 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 @@ -69,7 +69,7 @@ U Javi bi zadnja linija prethodnog primjera bila tačna. Za čvorove oba grafa, Java bi dodijelila isti tip `Graph.Node`; npr. `Node` bi imala prefiks klase `Graph`. 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: - + ```scala mdoc:nest class Graph { class Node { @@ -88,6 +88,6 @@ class Graph { } } ``` - + > Primijetite da ovaj program ne dozvoljava da dodamo čvor u dva različita grafa. Ako bi htjeli ukloniti i ovo ograničenje, moramo promijeniti tipski parametar `nodes` u `Graph#Node`. diff --git a/_es/tour/inner-classes.md b/_es/tour/inner-classes.md index 461c72eeb1..6a8aee1fea 100644 --- a/_es/tour/inner-classes.md +++ b/_es/tour/inner-classes.md @@ -15,7 +15,7 @@ En Scala es posible que las clases tengan como miembro otras clases. A diferenci class Graph { class Node { var connectedNodes: List[Node] = Nil - def connectTo(node: Node) { + def connectTo(node: Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } diff --git a/_ja/tour/inner-classes.md b/_ja/tour/inner-classes.md index 2bc8ecf450..d3687e69a7 100644 --- a/_ja/tour/inner-classes.md +++ b/_ja/tour/inner-classes.md @@ -19,7 +19,7 @@ Javaのような、内部クラスが外側のクラスのメンバーとなる class Graph { class Node { var connectedNodes: List[Node] = Nil - def connectTo(node: Node) { + def connectTo(node: Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } diff --git a/_ko/tour/inner-classes.md b/_ko/tour/inner-classes.md index 173449ef43..b135f5893f 100644 --- a/_ko/tour/inner-classes.md +++ b/_ko/tour/inner-classes.md @@ -11,11 +11,11 @@ previous-page: lower-type-bounds --- 스칼라의 클래스는 다른 클래스를 멤버로 가질 수 있다. 자바와 같은 언어의 내부 클래스는 자신을 감싸고 있는 클래스의 멤버인 반면에, 스칼라에선 내부 클래스가 외부 객체의 경계 안에 있다. 이런 차이점을 분명히 하기 위해 그래프 데이터타입의 구현을 간단히 그려보자. - + class Graph { class Node { var connectedNodes: List[Node] = Nil - def connectTo(node: Node) { + def connectTo(node: Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } @@ -28,9 +28,9 @@ previous-page: lower-type-bounds res } } - + 이 프로그램에선 노드의 리스트로 그래프를 나타냈다. 노드는 내부 클래스 `Node`의 객체다. 각 노드는 리스트 `connectedNodes`에 저장되는 이웃의 목록을 갖고 있다. 이제 몇몇 노드를 선택하고 이에 연결된 노드를 추가하면서 점진적으로 그래프를 구축할 수 있다. - + object GraphTest extends App { val g = new Graph val n1 = g.newNode @@ -39,9 +39,9 @@ previous-page: lower-type-bounds n1.connectTo(n2) n3.connectTo(n1) } - + 정의된 여러 엔티티의 타입이 무엇인지 명시적으로 알려주는 타입 정보를 사용해 위의 예제를 확장해보자. - + object GraphTest extends App { val g: Graph = new Graph val n1: g.Node = g.newNode @@ -50,10 +50,10 @@ previous-page: lower-type-bounds n1.connectTo(n2) n3.connectTo(n1) } - + 이 코드는 외부 인스턴스(이 예제의 객체 `g`)를 접두어로 지정해 노드 타입을 분명히 나타내고 있다. 두 그래프가 있는 상황에서, 스칼라의 타입 시스템은 한 그래프에 정의된 노드를 다른 그래프에서도 정의해 공유하는 상황을 허용하지 않는다. 이는 다른 그래프의 노드는 다른 타입을 갖기 때문이다. 다음은 잘못된 프로그램이다. - + object IllegalGraphTest extends App { val g: Graph = new Graph val n1: g.Node = g.newNode @@ -63,9 +63,9 @@ previous-page: lower-type-bounds val n3: h.Node = h.newNode n1.connectTo(n3) // illegal! } - + 자바에선 이 예제 프로그램의 마지막 줄이 올바른 표현임을 상기하자. 자바는 두 그래프의 노드에 `Graph.Node`라는 동일한 타입을 할당한다. 즉, `Node`에는 클래스 `Graph`가 접두어로 붙는다. 스칼라에서도 이런 타입을 표현할 수 있으며, 이를 `Graph#Node`로 나타낸다. 서로 다른 그래프 간에 노드를 연결할 수 있길 원한다면 초기 그래프 구현의 정의를 다음과 같이 변경해야 한다. - + class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil @@ -82,7 +82,7 @@ previous-page: lower-type-bounds res } } - + > 이 프로그램에선 하나의 노드를 서로 다른 두 그래프에 추가할 수 없음에 주의하자. 이 제약도 함께 제거하기 위해선 변수 nodes의 타입을 `Graph#Node`로 바꿔야 한다. 윤창석, 이한욱 옮김 diff --git a/_pl/tour/inner-classes.md b/_pl/tour/inner-classes.md index 2f3fef4ea1..6cbde222ac 100644 --- a/_pl/tour/inner-classes.md +++ b/_pl/tour/inner-classes.md @@ -10,12 +10,12 @@ 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: - + ```scala mdoc class Graph { class Node { var connectedNodes: List[Node] = Nil - def connectTo(node: Node) { + def connectTo(node: Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } @@ -29,9 +29,9 @@ 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ą: - + ```scala mdoc object GraphTest extends App { val g = new Graph @@ -42,9 +42,9 @@ object GraphTest extends App { n3.connectTo(n1) } ``` - + Teraz wzbogacimy nasz przykład o jawne typowanie, aby można było zobaczyć powiązanie typów wierzchołków z grafem: - + ```scala mdoc:nest object GraphTest extends App { val g: Graph = new Graph @@ -55,11 +55,11 @@ object GraphTest extends App { n3.connectTo(n1) } ``` - + Ten kod pokazuje, że typ wierzchołka jest prefiksowany przez swoją zewnętrzną instancję (która jest obiektem `g` w naszym przykładzie). Jeżeli mielibyśmy dwa grafy, system typów w Scali nie pozwoli nam na pomieszanie wierzchołków jednego z wierzchołkami drugiego, ponieważ wierzchołki drugiego grafu są określone przez inny typ. Przykład niedopuszczalnego programu: - + ```scala mdoc:fail object IllegalGraphTest extends App { val g: Graph = new Graph @@ -71,9 +71,9 @@ object IllegalGraphTest extends App { n1.connectTo(n3) // niedopuszczalne! } ``` - + 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: - + ```scala mdoc:nest class Graph { class Node { @@ -92,5 +92,5 @@ class Graph { } } ``` - + > Ważne jest, że ten program nie pozwala nam na dołączenie wierzchołka do dwóch różnych grafów. Jeżeli chcielibyśmy znieść to ograniczenie, należy zmienić typ zmiennej `nodes` na `Graph#Node`. diff --git a/_pt-br/tour/inner-classes.md b/_pt-br/tour/inner-classes.md index aff2633035..b0fc8e27bf 100644 --- a/_pt-br/tour/inner-classes.md +++ b/_pt-br/tour/inner-classes.md @@ -15,7 +15,7 @@ Em Scala é possível declarar classes que tenham outras classes como membros. E class Graph { class Node { var connectedNodes: List[Node] = Nil - def connectTo(node: Node) { + def connectTo(node: Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } @@ -31,7 +31,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: - + ```scala mdoc object GraphTest extends App { val g = new Graph @@ -44,7 +44,7 @@ object GraphTest extends App { ``` Agora melhoramos o exemplo acima com tipos, para assim declarar explicitamente qual o tipo das várias entidades definidas: - + ```scala mdoc:nest object GraphTest extends App { val g: Graph = new Graph @@ -58,7 +58,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: - + ```scala mdoc:fail object IllegalGraphTest extends App { val g: Graph = new Graph @@ -72,7 +72,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: - + ```scala mdoc:nest class Graph { class Node { diff --git a/_ru/tour/inner-classes.md b/_ru/tour/inner-classes.md index 9d86b84000..0f2a0f1f8d 100644 --- a/_ru/tour/inner-classes.md +++ b/_ru/tour/inner-classes.md @@ -8,7 +8,7 @@ next-page: abstract-type-members previous-page: lower-type-bounds --- -В Scala классам можно иметь в качестве членов другие классы. В отличие от Java-подобных языков, где такие внутренние классы являются членами окружающего класса, в Scala такие внутренние классы привязаны к содержащему его объекту. Предположим, мы хотим, чтобы компилятор не позволял нам на этапе компиляции смешивать узлы этого графа. Для решения этой задачи нам подойдут типы, зависящие от своего расположения. +В Scala классам можно иметь в качестве членов другие классы. В отличие от Java-подобных языков, где такие внутренние классы являются членами окружающего класса, в Scala такие внутренние классы привязаны к содержащему его объекту. Предположим, мы хотим, чтобы компилятор не позволял нам на этапе компиляции смешивать узлы этого графа. Для решения этой задачи нам подойдут типы, зависящие от своего расположения. Чтобы проиллюстрировать суть подхода, мы быстро набросаем реализацию такого графа: @@ -16,7 +16,7 @@ previous-page: lower-type-bounds class Graph { class Node { var connectedNodes: List[Node] = Nil - def connectTo(node: Node) { + def connectTo(node: Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } diff --git a/_zh-cn/tour/inner-classes.md b/_zh-cn/tour/inner-classes.md index d8fede0742..fbced6ed33 100644 --- a/_zh-cn/tour/inner-classes.md +++ b/_zh-cn/tour/inner-classes.md @@ -19,7 +19,7 @@ previous-page: lower-type-bounds class Graph { class Node { var connectedNodes: List[Node] = Nil - def connectTo(node: Node) { + def connectTo(node: Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } @@ -77,4 +77,3 @@ class Graph { } } ``` - From f42f33e065ed87f4c353643913ffbc5c2ae9bfd6 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 18:15:21 +0200 Subject: [PATCH 06/16] remove some more procedure syntax --- _ba/tour/inner-classes.md | 2 +- _es/tour/inner-classes.md | 2 +- _ja/tour/inner-classes.md | 2 +- _ko/tour/inner-classes.md | 2 +- _pl/tour/inner-classes.md | 2 +- _pt-br/tour/inner-classes.md | 2 +- _ru/tour/inner-classes.md | 2 +- _zh-cn/tour/inner-classes.md | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/_ba/tour/inner-classes.md b/_ba/tour/inner-classes.md index dade40c827..ef72aa8929 100644 --- a/_ba/tour/inner-classes.md +++ b/_ba/tour/inner-classes.md @@ -74,7 +74,7 @@ Ako želimo povezati čvorove različitih grafova, moramo promijeniti definiciju class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil - def connectTo(node: Graph#Node) { + def connectTo(node: Graph#Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } diff --git a/_es/tour/inner-classes.md b/_es/tour/inner-classes.md index 6a8aee1fea..16642d584c 100644 --- a/_es/tour/inner-classes.md +++ b/_es/tour/inner-classes.md @@ -70,7 +70,7 @@ Por favor note que en Java la última linea del ejemplo anterior hubiese sido co class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil // Graph#Node en lugar de Node - def connectTo(node: Graph#Node) { + def connectTo(node: Graph#Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } diff --git a/_ja/tour/inner-classes.md b/_ja/tour/inner-classes.md index d3687e69a7..60916409b4 100644 --- a/_ja/tour/inner-classes.md +++ b/_ja/tour/inner-classes.md @@ -69,7 +69,7 @@ Scalaではそのような型も同様に表現することができ、`Graph#No class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil - def connectTo(node: Graph#Node) { + def connectTo(node: Graph#Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } diff --git a/_ko/tour/inner-classes.md b/_ko/tour/inner-classes.md index b135f5893f..f593ac9986 100644 --- a/_ko/tour/inner-classes.md +++ b/_ko/tour/inner-classes.md @@ -69,7 +69,7 @@ previous-page: lower-type-bounds class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil - def connectTo(node: Graph#Node) { + def connectTo(node: Graph#Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } diff --git a/_pl/tour/inner-classes.md b/_pl/tour/inner-classes.md index 6cbde222ac..3440faee7e 100644 --- a/_pl/tour/inner-classes.md +++ b/_pl/tour/inner-classes.md @@ -78,7 +78,7 @@ Warto zwrócić uwagę na to, że ostatnia linia poprzedniego przykładu byłaby class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil - def connectTo(node: Graph#Node) { + def connectTo(node: Graph#Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } diff --git a/_pt-br/tour/inner-classes.md b/_pt-br/tour/inner-classes.md index b0fc8e27bf..692070bcc7 100644 --- a/_pt-br/tour/inner-classes.md +++ b/_pt-br/tour/inner-classes.md @@ -77,7 +77,7 @@ Observe que em Java a última linha no programa do exemplo anterior é válida. class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil - def connectTo(node: Graph#Node) { + def connectTo(node: Graph#Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } diff --git a/_ru/tour/inner-classes.md b/_ru/tour/inner-classes.md index 0f2a0f1f8d..5e1d075e90 100644 --- a/_ru/tour/inner-classes.md +++ b/_ru/tour/inner-classes.md @@ -60,7 +60,7 @@ node1.connectTo(node3) // не работает! class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil - def connectTo(node: Graph#Node) { + def connectTo(node: Graph#Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } diff --git a/_zh-cn/tour/inner-classes.md b/_zh-cn/tour/inner-classes.md index fbced6ed33..a390c0b340 100644 --- a/_zh-cn/tour/inner-classes.md +++ b/_zh-cn/tour/inner-classes.md @@ -63,7 +63,7 @@ node1.connectTo(node3) // illegal! class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil - def connectTo(node: Graph#Node) { + def connectTo(node: Graph#Node): Unit = { if (!connectedNodes.exists(node.equals)) { connectedNodes = node :: connectedNodes } From 58a70c83e0d1133df3683610496fe1cdca33b454 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 18:19:11 +0200 Subject: [PATCH 07/16] drop lossy implicit conversion --- _ba/tour/unified-types.md | 18 +++++++++--------- _ja/tour/unified-types.md | 4 ++-- _ko/tour/unified-types.md | 6 +++--- _pl/tour/unified-types.md | 10 +++++----- _ru/tour/unified-types.md | 4 ++-- _th/tour/unified-types.md | 4 ++-- _tour/unified-types.md | 4 ++-- _zh-cn/tour/unified-types.md | 4 ++-- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/_ba/tour/unified-types.md b/_ba/tour/unified-types.md index c03e54ab0b..92c1e2a61e 100644 --- a/_ba/tour/unified-types.md +++ b/_ba/tour/unified-types.md @@ -18,14 +18,14 @@ Dijagram ispod prikazuje hijerarhiju Scala klasa. ## Hijerarhija tipova u Scali ## -[`Any`](https://www.scala-lang.org/api/2.12.1/scala/Any.html) je nadtip svih tipova, zove se još i vrh-tip. +[`Any`](https://www.scala-lang.org/api/2.12.1/scala/Any.html) je nadtip svih tipova, zove se još i vrh-tip. Definiše određene univerzalne metode kao što su `equals`, `hashCode` i `toString`. `Any` ima dvije direktne podklase, `AnyVal` i `AnyRef`. -`AnyVal` predstavlja vrijednosne tipove. Postoji devet predefinisanih vrijednosnih tipova i oni ne mogu biti `null`: +`AnyVal` predstavlja vrijednosne tipove. Postoji devet predefinisanih vrijednosnih tipova i oni ne mogu biti `null`: `Double`, `Float`, `Long`, `Int`, `Short`, `Byte`, `Char`, `Unit` i `Boolean`. -`Unit` je vrijednosni tip koji ne nosi značajnu informaciju. Postoji tačno jedna instanca tipa `Unit` koja se piše `()`. +`Unit` je vrijednosni tip koji ne nosi značajnu informaciju. Postoji tačno jedna instanca tipa `Unit` koja se piše `()`. Sve funkcije moraju vratiti nešto tako da je `Unit` ponekad koristan povratni tip. `AnyRef` predstavlja referencne tipove. Svi nevrijednosni tipovi definišu se kao referencni. @@ -66,7 +66,7 @@ Npr: ```scala mdoc val x: Long = 987654321 -val y: Float = x // 9.8765434E8 (određena doza preciznosti se gubi ovdje) +val y: Float = x.toFloat // 9.8765434E8 (određena doza preciznosti se gubi ovdje) val face: Char = '☺' val number: Int = face // 9786 @@ -76,17 +76,17 @@ Kastovanje je jednosmjerno. Ovo se ne kompajlira: ``` val x: Long = 987654321 -val y: Float = x // 9.8765434E8 +val y: Float = x.toFloat // 9.8765434E8 val z: Long = y // Does not conform ``` Također možete kastovati i referencni tip u podtip. Ovo će biti pokriveno kasnije. ## Nothing i Null -`Nothing` je podtip svih tipova, također se zove i donji tip (en. bottom type). Ne postoji vrijednost koja ima tip `Nothing`. +`Nothing` je podtip svih tipova, također se zove i donji tip (en. bottom type). Ne postoji vrijednost koja ima tip `Nothing`. Česta upotreba ovog tipa je signalizacija neterminacije kao što je bacanje izuzetka, izlaz iz programa, ili beskonačna petlja (tj. tip izraza koji se ne izračunava u vrijednost, ili metoda koja se ne završava normalno). -`Null` je podtip svih referencnih tipova (tj. bilo kog podtipa `AnyRef`). -Ima jednu vrijednost koja se piše literalom `null`. -`Null` se uglavnom koristi radi interoperabilnosti s ostalim JVM jezicima i skoro nikad se ne koristi u Scala kodu. +`Null` je podtip svih referencnih tipova (tj. bilo kog podtipa `AnyRef`). +Ima jednu vrijednost koja se piše literalom `null`. +`Null` se uglavnom koristi radi interoperabilnosti s ostalim JVM jezicima i skoro nikad se ne koristi u Scala kodu. Alternative za `null` obradićemo kasnije. diff --git a/_ja/tour/unified-types.md b/_ja/tour/unified-types.md index a12895c677..28e44ad510 100644 --- a/_ja/tour/unified-types.md +++ b/_ja/tour/unified-types.md @@ -64,7 +64,7 @@ true ```scala mdoc val x: Long = 987654321 -val y: Float = x // 9.8765434E8 (この場合精度が落ちることに注意してください) +val y: Float = x.toFloat // 9.8765434E8 (この場合精度が落ちることに注意してください) val face: Char = '☺' val number: Int = face // 9786 @@ -74,7 +74,7 @@ val number: Int = face // 9786 ``` val x: Long = 987654321 -val y: Float = x // 9.8765434E8 +val y: Float = x.toFloat // 9.8765434E8 val z: Long = y // 一致しない ``` diff --git a/_ko/tour/unified-types.md b/_ko/tour/unified-types.md index 989ef50d6b..0e12a3aaff 100644 --- a/_ko/tour/unified-types.md +++ b/_ko/tour/unified-types.md @@ -59,7 +59,7 @@ true ```scala mdoc val x: Long = 987654321 -val y: Float = x // 9.8765434E8 (이 경우 일부 자리수가 소실되었음을 주의) +val y: Float = x.toFloat // 9.8765434E8 (이 경우 일부 자리수가 소실되었음을 주의) val face: Char = '☺' val number: Int = face // 9786 @@ -69,7 +69,7 @@ val number: Int = face // 9786 ``` val x: Long = 987654321 -val y: Float = x // 9.8765434E8 +val y: Float = x.toFloat // 9.8765434E8 val z: Long = y // 적합하지 않음(캐스팅 불가) ``` @@ -78,4 +78,4 @@ val z: Long = y // 적합하지 않음(캐스팅 불가) # Nothing과 Null `Nothing`은 모든 타입의 서브타입이며, 바텀타입이라고도 합니다. `Nothing`은 값이 없음을 의미하는 타입니다. 일반적으로 예외 발생, 프로그램 종료 또는 무한 루프와 같은 비 종료 신호를 보내는 용도로 사용합니다 (즉, 값으로 평가되지 않는 표현식의 타입 또는 정상적으로 반환되지 않는 메소드). -`Null`은 모든 참조 타입의 서브타입입니다(즉, AnyRef의 모든 서브타입). 예약어 `null`로 식별되는 단일 값을 갖습니다. `Null`은 주로 다른 JVM 언어와의 상호 운용성을 위해 제공되며 스칼라 코드에서는 거의 사용되지 않아야합니다. 우리는 투어에서 나중에 `null`에 대한 대안을 다룰 것입니다. +`Null`은 모든 참조 타입의 서브타입입니다(즉, AnyRef의 모든 서브타입). 예약어 `null`로 식별되는 단일 값을 갖습니다. `Null`은 주로 다른 JVM 언어와의 상호 운용성을 위해 제공되며 스칼라 코드에서는 거의 사용되지 않아야합니다. 우리는 투어에서 나중에 `null`에 대한 대안을 다룰 것입니다. diff --git a/_pl/tour/unified-types.md b/_pl/tour/unified-types.md index 1845401acd..831b720bb8 100644 --- a/_pl/tour/unified-types.md +++ b/_pl/tour/unified-types.md @@ -70,7 +70,7 @@ Dla przykładu: ```scala mdoc val x: Long = 987654321 -val y: Float = x // 9.8765434E8 (w tym wypadku tracimy część precyzji) +val y: Float = x.toFloat // 9.8765434E8 (w tym wypadku tracimy część precyzji) val face: Char = '☺' val number: Int = face // 9786 @@ -80,7 +80,7 @@ Rzutowanie jest jednokierunkowe, następujący kod nie zadziała: ``` val x: Long = 987654321 -val y: Float = x // 9.8765434E8 +val y: Float = x.toFloat // 9.8765434E8 val z: Long = y // Błąd: Does not conform ``` @@ -91,11 +91,11 @@ Zostanie to dokładniej omówione w kolejnych rozdziałach. `Nothing` jest podtypem wszystkich typów, istnieje na samym dole hierarchii i jest nazywany typem dolnym (bottom type). Nie istnieje żadna wartość typu `Nothing`. -Częstym przykładem użycia jest zasygnalizowanie stanów nieoznaczonych np. wyrzucony wyjątek, wyjście z programu, -nieskończona pętla (ściślej mówiąc - jest to typ wyrażenia które nie ewaluuje na żadną wartość lub metoda, która nie zwraca wyniku). +Częstym przykładem użycia jest zasygnalizowanie stanów nieoznaczonych np. wyrzucony wyjątek, wyjście z programu, +nieskończona pętla (ściślej mówiąc - jest to typ wyrażenia które nie ewaluuje na żadną wartość lub metoda, która nie zwraca wyniku). `Null` jest podtypem wszystkich typów referencyjnych (wszystkich podtypów `AnyRef`). Ma pojedynczą wartosć identyfikowaną przez słowo kluczowe `null`. -`Null` przydaje się głównie do współpracy z innymi językami platformy JVM i nie powinien być praktycznie nigdy używany +`Null` przydaje się głównie do współpracy z innymi językami platformy JVM i nie powinien być praktycznie nigdy używany w kodzie w jęzku Scala. W dalszej części przewodnika omówimy alternatywy dla `null`. diff --git a/_ru/tour/unified-types.md b/_ru/tour/unified-types.md index 7399f82409..7b692d363e 100644 --- a/_ru/tour/unified-types.md +++ b/_ru/tour/unified-types.md @@ -55,7 +55,7 @@ true ```scala mdoc val x: Long = 987654321 -val y: Float = x // 9.8765434E8 (заметьте, что некоторая точность теряется в этом случае.) +val y: Float = x.toFloat // 9.8765434E8 (заметьте, что некоторая точность теряется в этом случае.) val face: Char = '☺' val number: Int = face // 9786 @@ -65,7 +65,7 @@ val number: Int = face // 9786 ``` val x: Long = 987654321 -val y: Float = x // 9.8765434E8 +val y: Float = x.toFloat // 9.8765434E8 val z: Long = y // обратно не подходит ``` diff --git a/_th/tour/unified-types.md b/_th/tour/unified-types.md index 7e92c8a39f..4c2b24c48a 100644 --- a/_th/tour/unified-types.md +++ b/_th/tour/unified-types.md @@ -57,7 +57,7 @@ Value type สามารถแปลได้ด้วยวิธีดัง ```scala mdoc val x: Long = 987654321 -val y: Float = x // 9.8765434E8 (หมายเหตุว่าค่าความละเอียดจะสูญหายไปในกรณีนี้) +val y: Float = x.toFloat // 9.8765434E8 (หมายเหตุว่าค่าความละเอียดจะสูญหายไปในกรณีนี้) val face: Char = '☺' val number: Int = face // 9786 @@ -67,7 +67,7 @@ val number: Int = face // 9786 ``` val x: Long = 987654321 -val y: Float = x // 9.8765434E8 +val y: Float = x.toFloat // 9.8765434E8 val z: Long = y // ไม่เป็นไปตามที่ต้องการ ``` diff --git a/_tour/unified-types.md b/_tour/unified-types.md index b93de3e277..191dc28c1e 100644 --- a/_tour/unified-types.md +++ b/_tour/unified-types.md @@ -63,7 +63,7 @@ For example: {% tab 'Scala 2 and 3' for=unified-types-2 %} ```scala mdoc val x: Long = 987654321 -val y: Float = x // 9.8765434E8 (note that some precision is lost in this case) +val y: Float = x.toFloat // 9.8765434E8 (note that some precision is lost in this case) val face: Char = '☺' val number: Int = face // 9786 @@ -78,7 +78,7 @@ Casting is unidirectional. This will not compile: {% tab 'Scala 2 and 3' for=unified-types-3 %} ```scala val x: Long = 987654321 -val y: Float = x // 9.8765434E8 +val y: Float = x.toFloat // 9.8765434E8 val z: Long = y // Does not conform ``` {% endtab %} diff --git a/_zh-cn/tour/unified-types.md b/_zh-cn/tour/unified-types.md index b3d9055168..904684e4dc 100644 --- a/_zh-cn/tour/unified-types.md +++ b/_zh-cn/tour/unified-types.md @@ -59,7 +59,7 @@ true ```scala mdoc val x: Long = 987654321 -val y: Float = x // 9.8765434E8 (note that some precision is lost in this case) +val y: Float = x.toFloat // 9.8765434E8 (note that some precision is lost in this case) val face: Char = '☺' val number: Int = face // 9786 @@ -69,7 +69,7 @@ val number: Int = face // 9786 ``` val x: Long = 987654321 -val y: Float = x // 9.8765434E8 +val y: Float = x.toFloat // 9.8765434E8 val z: Long = y // Does not conform ``` From ead8a172c18aad2e263635078d875f59b0825352 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 18:23:40 +0200 Subject: [PATCH 08/16] use more string interpolators take 2 --- _ja/tour/basics.md | 10 +++++----- _pl/tour/basics.md | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/_ja/tour/basics.md b/_ja/tour/basics.md index 1108cbf3ba..40123f7faa 100644 --- a/_ja/tour/basics.md +++ b/_ja/tour/basics.md @@ -63,7 +63,7 @@ x = 3 // この記述はコンパイルされません。 val x: Int = 1 + 1 ``` -型定義では`Int` は識別子`x`の後にくることに注意してください。そして`:`も必要となります。 +型定義では`Int` は識別子`x`の後にくることに注意してください。そして`:`も必要となります。 ### 変数 @@ -210,15 +210,15 @@ val yetAnotherPoint = Point(2, 2) ```scala mdoc if (point == anotherPoint) { - println(point + " と " + anotherPoint + " は同じです。") + println(s"$point と $anotherPoint は同じです。") } else { - println(point + " と " + anotherPoint + " は異なります。") + println(s"$point と $anotherPoint は異なります。") } // Point(1,2) と Point(1,2) は同じです。 if (point == yetAnotherPoint) { - println(point + " と " + yetAnotherPoint + " は同じです。") + println(s"$point と $yetAnotherPoint は同じです。") } else { - println(point + " と " + yetAnotherPoint + " は異なります。") + println(s"$point と $yetAnotherPoint は異なります。") } // Point(1,2) と Point(2,2) は異なります。 ``` diff --git a/_pl/tour/basics.md b/_pl/tour/basics.md index d9083fb1cf..816fd5893a 100644 --- a/_pl/tour/basics.md +++ b/_pl/tour/basics.md @@ -220,15 +220,15 @@ Są one porównywane przez wartości - _nie_ przez referencje. ```scala mdoc if (point == anotherPoint) { - println(point + " i " + anotherPoint + " są jednakowe.") + println(s"$point i $anotherPoint są jednakowe.") } else { - println(point + " i " + anotherPoint + " są inne.") + println(s"$point i $anotherPoint są inne.") } // Point(1,2) i Point(1,2) są jednakowe. if (point == yetAnotherPoint) { - println(point + " i " + yetAnotherPoint + " są jednakowe.") + println(s"$point i $yetAnotherPoint są jednakowe.") } else { - println(point + " i " + yetAnotherPoint + " są inne.") + println(s"$point i $yetAnotherPoint są inne.") } // Point(1,2) i Point(2,2) są inne. ``` From 2b7a9358c48264c7b25f03b10c651c8d7dcb2379 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 18:30:09 +0200 Subject: [PATCH 09/16] remove App wrapper objects --- _es/tour/abstract-type-members.md | 18 +++++++------- _ko/tour/abstract-type-members.md | 34 ++++++++++++--------------- _pl/tour/abstract-type-members.md | 35 +++++++++++++--------------- _pt-br/tour/abstract-type-members.md | 18 +++++++------- _tour/abstract-type-members.md | 8 +++---- 5 files changed, 51 insertions(+), 62 deletions(-) diff --git a/_es/tour/abstract-type-members.md b/_es/tour/abstract-type-members.md index 841fa8778e..1e9afc50d7 100644 --- a/_es/tour/abstract-type-members.md +++ b/_es/tour/abstract-type-members.md @@ -40,16 +40,14 @@ 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) -} +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]`. diff --git a/_ko/tour/abstract-type-members.md b/_ko/tour/abstract-type-members.md index ba79514b11..b57ea05c11 100644 --- a/_ko/tour/abstract-type-members.md +++ b/_ko/tour/abstract-type-members.md @@ -36,16 +36,14 @@ previous-page: inner-classes 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) - } + 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) 메소드 `newIntSeqBuf`의 반환 타입은 트레잇 `Buffer`의 특수화를 따르며, 타입 `U`가 `Int`와 같아진다. 메소드 `newIntSeqBuf` 내부의 익명 클래스 인스턴스화에서도 비슷한 타입 별칭이 있다. 여기선 `T` 타입이 `List[Int]`를 가리키는 `IntSeqBuf`의 새로운 인스턴스를 생성한다. @@ -57,15 +55,13 @@ previous-page: inner-classes 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) 여기선 [가변성 어노테이션](variances.html)을 사용해야만 한다는 점에 유의하자. 이를 사용하지 않으면 메소드 `newIntSeqBuf`에서 반환되는 객체의 특정 시퀀스 구현 타입을 감출 수 없게 된다. 뿐만 아니라 추상 타입을 타입 파라미터로 대체할 수 없는 경우도 있다. diff --git a/_pl/tour/abstract-type-members.md b/_pl/tour/abstract-type-members.md index d47ebe86af..e79d551939 100644 --- a/_pl/tour/abstract-type-members.md +++ b/_pl/tour/abstract-type-members.md @@ -39,16 +39,14 @@ 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) -} +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) ``` Typ zwracany przez metodę `newIntSeqBuf` nawiązuje do specjalizacji cechy `Buffer`, w której typ `U` jest równy `Int`. Podobnie w anonimowej klasie tworzonej w metodzie `newIntSeqBuf` określamy `T` jako `List[Int]`. @@ -62,15 +60,14 @@ abstract class Buffer[+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) ``` Należy też pamiętać o zastosowaniu [adnotacji wariancji](variances.html). Inaczej nie byłoby możliwe ukrycie konkretnego typu sekwencji obiektu zwracanego przez metodę `newIntSeqBuf`. diff --git a/_pt-br/tour/abstract-type-members.md b/_pt-br/tour/abstract-type-members.md index 8a798f4468..e8dba1011c 100644 --- a/_pt-br/tour/abstract-type-members.md +++ b/_pt-br/tour/abstract-type-members.md @@ -39,16 +39,14 @@ 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) -} +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) ``` O tipo de retorno do método `newIntSeqBuf` refere-se a uma especialização da trait `Buffer` no qual o tipo `U` é agora equivalente a `Int`. Declaramos um tipo *alias* semelhante ao que temos na instanciação da classe anônima dentro do corpo do método `newIntSeqBuf`. Criamos uma nova instância de `IntSeqBuffer` na qual o tipo `T` refere-se a `List[Int]`. diff --git a/_tour/abstract-type-members.md b/_tour/abstract-type-members.md index 77dedcc386..ff6a2b3ddd 100644 --- a/_tour/abstract-type-members.md +++ b/_tour/abstract-type-members.md @@ -8,7 +8,7 @@ previous-page: inner-classes topics: abstract type members prerequisite-knowledge: variance, upper-type-bound -redirect_from: +redirect_from: - "/tutorials/tour/abstract-types.html" - "/tour/abstract-types.html" --- @@ -44,9 +44,9 @@ abstract class IntSeqBuffer extends SeqBuffer { def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer = new IntSeqBuffer { - type T = List[U] - val element = List(elem1, elem2) - } + type T = List[U] + val element = List(elem1, elem2) + } val buf = newIntSeqBuf(7, 8) println("length = " + buf.length) println("content = " + buf.element) From 2740775b1f9369242da735ed4d7e2766f020cb23 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 18:37:14 +0200 Subject: [PATCH 10/16] remove some more proc syntax --- _es/tour/automatic-closures.md | 2 +- _es/tour/generic-classes.md | 16 +++++++++------- _ja/tour/automatic-closures.md | 2 +- _ko/tour/automatic-closures.md | 2 +- _ko/tour/generic-classes.md | 16 +++++++++------- _pl/tour/automatic-closures.md | 3 +-- _pl/tour/generic-classes.md | 4 ++-- _pt-br/tour/automatic-closures.md | 2 +- _pt-br/tour/generic-classes.md | 2 +- _ru/tour/automatic-closures.md | 2 +- _tour/automatic-closures.md | 31 +++++++++++++++++-------------- 11 files changed, 44 insertions(+), 38 deletions(-) diff --git a/_es/tour/automatic-closures.md b/_es/tour/automatic-closures.md index bb26c5a665..5d8cb2f998 100644 --- a/_es/tour/automatic-closures.md +++ b/_es/tour/automatic-closures.md @@ -37,7 +37,7 @@ Aquí mostramos la implementación de una declaración tipo repetir-a-menos-que def loop(body: => Unit): LoopUnlessCond = new LoopUnlessCond(body) protected class LoopUnlessCond(body: => Unit) { - def unless(cond: => Boolean) { + def unless(cond: => Boolean): Unit = { body if (!cond) unless(cond) } diff --git a/_es/tour/generic-classes.md b/_es/tour/generic-classes.md index 2a1ed5a2ba..b89b603ae3 100644 --- a/_es/tour/generic-classes.md +++ b/_es/tour/generic-classes.md @@ -14,13 +14,15 @@ Tal como en Java 5, Scala provee soporte nativo para clases parametrizados con t A continuación se muestra un ejemplo: - class Stack[T] { - var elems: List[T] = Nil - def push(x: T): Unit = - elems = x :: elems - def top: T = elems.head - def pop() { elems = elems.tail } - } +```scala mdoc +class Stack[T] { + var elems: List[T] = Nil + def push(x: T): Unit = + elems = x :: elems + def top: T = elems.head + def pop(): Unit = { elems = elems.tail } +} +``` La clase `Stack` modela una pila mutable que contiene elementos de un tipo arbitrario `T` (se dice, "una pila de elementos `T`). Los parámetros de tipos nos aseguran que solo elementos legales (o sea, del tipo `T`) sean insertados en la pila (apilados). De forma similar, con los parámetros de tipo podemos expresar que el método `top` solo devolverá elementos de un tipo dado (en este caso `T`). diff --git a/_ja/tour/automatic-closures.md b/_ja/tour/automatic-closures.md index 0ba4911aa2..80cb7edf7e 100644 --- a/_ja/tour/automatic-closures.md +++ b/_ja/tour/automatic-closures.md @@ -32,7 +32,7 @@ Scalaはメソッドのパラメータとしてパラメータ無しの関数名 def loop(body: => Unit): LoopUnlessCond = new LoopUnlessCond(body) protected class LoopUnlessCond(body: => Unit) { - def unless(cond: => Boolean) { + def unless(cond: => Boolean): Unit = { body if (!cond) unless(cond) } diff --git a/_ko/tour/automatic-closures.md b/_ko/tour/automatic-closures.md index 873828bb1b..639623c537 100644 --- a/_ko/tour/automatic-closures.md +++ b/_ko/tour/automatic-closures.md @@ -37,7 +37,7 @@ previous-page: operators def loop(body: => Unit): LoopUnlessCond = new LoopUnlessCond(body) protected class LoopUnlessCond(body: => Unit) { - def unless(cond: => Boolean) { + def unless(cond: => Boolean): Unit = { body if (!cond) unless(cond) } diff --git a/_ko/tour/generic-classes.md b/_ko/tour/generic-classes.md index 724514f338..4a7d70bf56 100644 --- a/_ko/tour/generic-classes.md +++ b/_ko/tour/generic-classes.md @@ -12,13 +12,15 @@ previous-page: extractor-objects 자바 5(다른 이름은 JDK 1.5와 같이, 스칼라는 타입으로 파라미터화된 클래스의 빌트인 지원을 제공한다. 이런 제네릭 클래스는 특히 컬렉션 클래스의 개발에 유용하다. 이에 관한 예제를 살펴보자. - class Stack[T] { - var elems: List[T] = Nil - def push(x: T): Unit = - elems = x :: elems - def top: T = elems.head - def pop() { elems = elems.tail } - } +```scala mdoc +class Stack[T] { + var elems: List[T] = Nil + def push(x: T): Unit = + elems = x :: elems + def top: T = elems.head + def pop(): Unit = { elems = elems.tail } +} +``` 클래스 `Stack`은 임의의 타입 `T`를 항목의 타입으로 하는 명령형(변경 가능한) 스택이다. 타입 파라미터는 올바른 항목(타입 `T` 인)만을 스택에 푸시하도록 강제한다. 마찬가지로 타입 파라미터를 사용해서 메소드 `top`이 항상 지정된 타입만을 반환하도록 할 수 있다. diff --git a/_pl/tour/automatic-closures.md b/_pl/tour/automatic-closures.md index 5f28a2568a..2b50e803e6 100644 --- a/_pl/tour/automatic-closures.md +++ b/_pl/tour/automatic-closures.md @@ -39,7 +39,7 @@ object TargetTest2 extends App { def loop(body: => Unit): LoopUnlessCond = new LoopUnlessCond(body) protected class LoopUnlessCond(body: => Unit) { - def unless(cond: => Boolean) { + def unless(cond: => Boolean): Unit = { body if (!cond) unless(cond) } @@ -68,4 +68,3 @@ i = 3 i = 2 i = 1 ``` - diff --git a/_pl/tour/generic-classes.md b/_pl/tour/generic-classes.md index e616453a84..ac011270b3 100644 --- a/_pl/tour/generic-classes.md +++ b/_pl/tour/generic-classes.md @@ -17,9 +17,9 @@ Poniższy przykład demonstruje zastosowanie parametrów generycznych: class Stack[T] { var elems: List[T] = Nil def push(x: T): Unit = - elems = x :: elems + elems = x :: elems def top: T = elems.head - def pop() { elems = elems.tail } + def pop(): Unit = { elems = elems.tail } } ``` diff --git a/_pt-br/tour/automatic-closures.md b/_pt-br/tour/automatic-closures.md index 2f9072a59d..81084cd575 100644 --- a/_pt-br/tour/automatic-closures.md +++ b/_pt-br/tour/automatic-closures.md @@ -41,7 +41,7 @@ object TargetTest2 extends App { def loop(body: => Unit): LoopUnlessCond = new LoopUnlessCond(body) protected class LoopUnlessCond(body: => Unit) { - def unless(cond: => Boolean) { + def unless(cond: => Boolean): Unit = { body if (!cond) unless(cond) } diff --git a/_pt-br/tour/generic-classes.md b/_pt-br/tour/generic-classes.md index ac8e2de5f6..b81c21c1a3 100644 --- a/_pt-br/tour/generic-classes.md +++ b/_pt-br/tour/generic-classes.md @@ -18,7 +18,7 @@ class Stack[T] { def push(x: T): Unit = elems = x :: elems def top: T = elems.head - def pop() { elems = elems.tail } + def pop(): Unit = { elems = elems.tail } } ``` diff --git a/_ru/tour/automatic-closures.md b/_ru/tour/automatic-closures.md index 7465e6abef..8f0a8d4451 100644 --- a/_ru/tour/automatic-closures.md +++ b/_ru/tour/automatic-closures.md @@ -33,7 +33,7 @@ Scala допускает использование в качестве пара def loop(body: => Unit): LoopUnlessCond = new LoopUnlessCond(body) protected class LoopUnlessCond(body: => Unit) { - def unless(cond: => Boolean) { + def unless(cond: => Boolean): Unit = { body if (!cond) unless(cond) } diff --git a/_tour/automatic-closures.md b/_tour/automatic-closures.md index 7df0b975ab..4e817b4dca 100644 --- a/_tour/automatic-closures.md +++ b/_tour/automatic-closures.md @@ -29,21 +29,24 @@ We can combine the use of [infix/postfix operators](operators.html) with this me Here is the implementation of a loop-unless statement: - object TargetTest2 extends Application { - def loop(body: => Unit): LoopUnlessCond = - new LoopUnlessCond(body) - protected class LoopUnlessCond(body: => Unit) { - def unless(cond: => Boolean) { - body - if (!cond) unless(cond) - } - } - var i = 10 - loop { - println("i = " + i) - i -= 1 - } unless (i == 0) +```scala mdoc +object TargetTest2 extends Application { + def loop(body: => Unit): LoopUnlessCond = + new LoopUnlessCond(body) + protected class LoopUnlessCond(body: => Unit) { + def unless(cond: => Boolean): Unit = { + body + if (!cond) unless(cond) } + } + var i = 10 + loop { + println("i = " + i) + i -= 1 + } unless (i == 0) +} +``` + The `loop` function just accepts a body of a loop and returns an instance of class `LoopUnlessCond` (which encapsulates this body object). Note that the body didn't get evaluated yet. Class `LoopUnlessCond` has a method `unless` which we can use as a *infix operator*. This way, we achieve a quite natural syntax for our new loop: `loop { < stats > } unless ( < cond > )`. Here's the output when `TargetTest2` gets executed: From 2c4f42d4d0bb0f0c651315400bdb3681f594906c Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 18:48:14 +0200 Subject: [PATCH 11/16] remove more app wrappers --- _es/tour/inner-classes.md | 36 ++++++++++++++++++++---------------- _es/tour/self-types.md | 20 +++++++++++--------- _ko/tour/inner-classes.md | 36 ++++++++++++++++++++---------------- _ko/tour/self-types.md | 20 +++++++++++--------- _pl/tour/inner-classes.md | 4 ++-- _pl/tour/self-types.md | 2 +- _pt-br/tour/inner-classes.md | 4 ++-- _pt-br/tour/self-types.md | 2 +- 8 files changed, 68 insertions(+), 56 deletions(-) diff --git a/_es/tour/inner-classes.md b/_es/tour/inner-classes.md index 16642d584c..8aa6563295 100644 --- a/_es/tour/inner-classes.md +++ b/_es/tour/inner-classes.md @@ -31,25 +31,29 @@ En Scala es posible que las clases tengan como miembro otras clases. A diferenci En nuestro programa, los grafos son representados mediante una lista de nodos. Estos nodos son objetos de la clase interna `Node`. Cada nodo tiene una lista de vecinos que se almacena en la lista `connectedNodes`. Ahora podemos crear un grafo con algunos nodos y conectarlos incrementalmente: - object GraphTest extends App { - val g = new Graph - val n1 = g.newNode - val n2 = g.newNode - val n3 = g.newNode - n1.connectTo(n2) - n3.connectTo(n1) - } +```scala mdoc +def graphTest: Unit = { + val g = new Graph + val n1 = g.newNode + val n2 = g.newNode + val n3 = g.newNode + n1.connectTo(n2) + n3.connectTo(n1) +} +``` Ahora vamos a completar el ejemplo con información relacionada al tipado para definir explicitamente de qué tipo son las entidades anteriormente definidas: - object GraphTest extends App { - val g: Graph = new Graph - val n1: g.Node = g.newNode - val n2: g.Node = g.newNode - val n3: g.Node = g.newNode - n1.connectTo(n2) - n3.connectTo(n1) - } +```scala mdoc:nest +def graphTest: Unit = { + val g: Graph = new Graph + val n1: g.Node = g.newNode + val n2: g.Node = g.newNode + val n3: g.Node = g.newNode + n1.connectTo(n2) + n3.connectTo(n1) +} +``` El código anterior muestra que al tipo del nodo le es prefijado con la instancia superior (que en nuestro ejemplo es `g`). Si ahora tenemos dos grafos, el sistema de tipado de Scala no nos permite mezclar nodos definidos en un grafo con nodos definidos en otro, ya que los nodos del otro grafo tienen un tipo diferente. diff --git a/_es/tour/self-types.md b/_es/tour/self-types.md index 79714212a7..025f22168f 100644 --- a/_es/tour/self-types.md +++ b/_es/tour/self-types.md @@ -91,12 +91,14 @@ Por favor nótese que en esta clase nos es posible instanciar `NodoImpl` porque Aquí hay un ejemplo de uso de la clase `GrafoDirigidoConcreto`: - object GraphTest extends App { - val g: Grafo = new GrafoDirigidoConcreto - val n1 = g.agregarNodo - val n2 = g.agregarNodo - val n3 = g.agregarNodo - n1.conectarCon(n2) - n2.conectarCon(n3) - n1.conectarCon(n3) - } +```scala mdoc +def graphTest: Unit = { + val g: Grafo = new GrafoDirigidoConcreto + val n1 = g.agregarNodo + val n2 = g.agregarNodo + val n3 = g.agregarNodo + n1.conectarCon(n2) + n2.conectarCon(n3) + n1.conectarCon(n3) +} +``` diff --git a/_ko/tour/inner-classes.md b/_ko/tour/inner-classes.md index f593ac9986..703525e34a 100644 --- a/_ko/tour/inner-classes.md +++ b/_ko/tour/inner-classes.md @@ -31,25 +31,29 @@ previous-page: lower-type-bounds 이 프로그램에선 노드의 리스트로 그래프를 나타냈다. 노드는 내부 클래스 `Node`의 객체다. 각 노드는 리스트 `connectedNodes`에 저장되는 이웃의 목록을 갖고 있다. 이제 몇몇 노드를 선택하고 이에 연결된 노드를 추가하면서 점진적으로 그래프를 구축할 수 있다. - object GraphTest extends App { - val g = new Graph - val n1 = g.newNode - val n2 = g.newNode - val n3 = g.newNode - n1.connectTo(n2) - n3.connectTo(n1) - } +```scala mdoc +def graphTest: Unit = { + val g = new Graph + val n1 = g.newNode + val n2 = g.newNode + val n3 = g.newNode + n1.connectTo(n2) + n3.connectTo(n1) +} +``` 정의된 여러 엔티티의 타입이 무엇인지 명시적으로 알려주는 타입 정보를 사용해 위의 예제를 확장해보자. - object GraphTest extends App { - val g: Graph = new Graph - val n1: g.Node = g.newNode - val n2: g.Node = g.newNode - val n3: g.Node = g.newNode - n1.connectTo(n2) - n3.connectTo(n1) - } +```scala mdoc:nest +def graphTest: Unit = { + val g: Graph = new Graph + val n1: g.Node = g.newNode + val n2: g.Node = g.newNode + val n3: g.Node = g.newNode + n1.connectTo(n2) + n3.connectTo(n1) +} +``` 이 코드는 외부 인스턴스(이 예제의 객체 `g`)를 접두어로 지정해 노드 타입을 분명히 나타내고 있다. 두 그래프가 있는 상황에서, 스칼라의 타입 시스템은 한 그래프에 정의된 노드를 다른 그래프에서도 정의해 공유하는 상황을 허용하지 않는다. 이는 다른 그래프의 노드는 다른 타입을 갖기 때문이다. 다음은 잘못된 프로그램이다. diff --git a/_ko/tour/self-types.md b/_ko/tour/self-types.md index 56ca99a2e6..ed3c8b7ad2 100644 --- a/_ko/tour/self-types.md +++ b/_ko/tour/self-types.md @@ -88,14 +88,16 @@ previous-page: compound-types 다음은 클래스 `ConcreteDirectedGraph`를 사용하는 예다. - object GraphTest extends App { - val g: Graph = new ConcreteDirectedGraph - val n1 = g.addNode - val n2 = g.addNode - val n3 = g.addNode - n1.connectWith(n2) - n2.connectWith(n3) - n1.connectWith(n3) - } +```scala mdoc +def graphTest: Unit = { + val g: Graph = new ConcreteDirectedGraph + val n1 = g.addNode + val n2 = g.addNode + val n3 = g.addNode + n1.connectWith(n2) + n2.connectWith(n3) + n1.connectWith(n3) +} +``` 윤창석, 이한욱 옮김 diff --git a/_pl/tour/inner-classes.md b/_pl/tour/inner-classes.md index 3440faee7e..687cff4801 100644 --- a/_pl/tour/inner-classes.md +++ b/_pl/tour/inner-classes.md @@ -33,7 +33,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ą: ```scala mdoc -object GraphTest extends App { +def graphTest: Unit = { val g = new Graph val n1 = g.newNode val n2 = g.newNode @@ -46,7 +46,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: ```scala mdoc:nest -object GraphTest extends App { +def graphTest: Unit = { val g: Graph = new Graph val n1: g.Node = g.newNode val n2: g.Node = g.newNode diff --git a/_pl/tour/self-types.md b/_pl/tour/self-types.md index 1bbb74be98..d0098d352c 100644 --- a/_pl/tour/self-types.md +++ b/_pl/tour/self-types.md @@ -110,7 +110,7 @@ Należy dodać, że w tej klasie możemy utworzyć `NodeImpl`, ponieważ wiemy j Poniżej przykład zastosowania klasy `ConcreteDirectedGraph`: ```scala mdoc -object GraphTest extends App { +def graphTest: Unit = { val g: Graph = new ConcreteDirectedGraph val n1 = g.addNode val n2 = g.addNode diff --git a/_pt-br/tour/inner-classes.md b/_pt-br/tour/inner-classes.md index 692070bcc7..694d9f4a35 100644 --- a/_pt-br/tour/inner-classes.md +++ b/_pt-br/tour/inner-classes.md @@ -33,7 +33,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: ```scala mdoc -object GraphTest extends App { +def graphTest: Unit = { val g = new Graph val n1 = g.newNode val n2 = g.newNode @@ -46,7 +46,7 @@ object GraphTest extends App { Agora melhoramos o exemplo acima com tipos, para assim declarar explicitamente qual o tipo das várias entidades definidas: ```scala mdoc:nest -object GraphTest extends App { +def graphTest: Unit = { val g: Graph = new Graph val n1: g.Node = g.newNode val n2: g.Node = g.newNode diff --git a/_pt-br/tour/self-types.md b/_pt-br/tour/self-types.md index 2596a83223..de2f95ef82 100644 --- a/_pt-br/tour/self-types.md +++ b/_pt-br/tour/self-types.md @@ -108,7 +108,7 @@ Observe que nesta classe, podemos instanciar `NodeImpl` porque agora sabemos que Aqui está um exemplo de uso da classe `ConcreteDirectedGraph`: ```scala mdoc -object GraphTest extends App { +def graphTest: Unit = { val g: Graph = new ConcreteDirectedGraph val n1 = g.addNode val n2 = g.addNode From 499e8ebea67c5928961b9251fdd63f7c9e74a9c0 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 18:50:36 +0200 Subject: [PATCH 12/16] add more mdoc --- _es/tour/inner-classes.md | 32 +++++++++++++++++--------------- _es/tour/self-types.md | 20 +++++++++----------- _ko/tour/inner-classes.md | 32 +++++++++++++++++--------------- _ko/tour/self-types.md | 20 +++++++++----------- _pl/tour/inner-classes.md | 2 +- _pt-br/tour/inner-classes.md | 2 +- 6 files changed, 54 insertions(+), 54 deletions(-) diff --git a/_es/tour/inner-classes.md b/_es/tour/inner-classes.md index 8aa6563295..9b04862d27 100644 --- a/_es/tour/inner-classes.md +++ b/_es/tour/inner-classes.md @@ -12,26 +12,28 @@ previous-page: implicit-parameters En Scala es posible que las clases tengan como miembro otras clases. A diferencia de lenguajes similares a Java donde ese tipo de clases internas son miembros de las clases que las envuelven, en Scala esas clases internas están ligadas al objeto externo. Para ilustrar esta diferencia, vamos a mostrar rápidamente una implementación del tipo grafo: - class Graph { - class Node { - var connectedNodes: List[Node] = Nil - def connectTo(node: Node): Unit = { - if (!connectedNodes.exists(node.equals)) { - connectedNodes = node :: connectedNodes - } - } - } - var nodes: List[Node] = Nil - def newNode: Node = { - val res = new Node - nodes = res :: nodes - res +```scala mdoc +class Graph { + class Node { + var connectedNodes: List[Node] = Nil + def connectTo(node: Node): Unit = { + if (!connectedNodes.exists(node.equals)) { + connectedNodes = node :: connectedNodes } } + } + var nodes: List[Node] = Nil + def newNode: Node = { + val res = new Node + nodes = res :: nodes + res + } +} +``` En nuestro programa, los grafos son representados mediante una lista de nodos. Estos nodos son objetos de la clase interna `Node`. Cada nodo tiene una lista de vecinos que se almacena en la lista `connectedNodes`. Ahora podemos crear un grafo con algunos nodos y conectarlos incrementalmente: -```scala mdoc +```scala mdoc:nest def graphTest: Unit = { val g = new Graph val n1 = g.newNode diff --git a/_es/tour/self-types.md b/_es/tour/self-types.md index 025f22168f..df02b7dc0a 100644 --- a/_es/tour/self-types.md +++ b/_es/tour/self-types.md @@ -91,14 +91,12 @@ Por favor nótese que en esta clase nos es posible instanciar `NodoImpl` porque Aquí hay un ejemplo de uso de la clase `GrafoDirigidoConcreto`: -```scala mdoc -def graphTest: Unit = { - val g: Grafo = new GrafoDirigidoConcreto - val n1 = g.agregarNodo - val n2 = g.agregarNodo - val n3 = g.agregarNodo - n1.conectarCon(n2) - n2.conectarCon(n3) - n1.conectarCon(n3) -} -``` + def graphTest: Unit = { + val g: Grafo = new GrafoDirigidoConcreto + val n1 = g.agregarNodo + val n2 = g.agregarNodo + val n3 = g.agregarNodo + n1.conectarCon(n2) + n2.conectarCon(n3) + n1.conectarCon(n3) + } diff --git a/_ko/tour/inner-classes.md b/_ko/tour/inner-classes.md index 703525e34a..309a4651a1 100644 --- a/_ko/tour/inner-classes.md +++ b/_ko/tour/inner-classes.md @@ -12,26 +12,28 @@ previous-page: lower-type-bounds 스칼라의 클래스는 다른 클래스를 멤버로 가질 수 있다. 자바와 같은 언어의 내부 클래스는 자신을 감싸고 있는 클래스의 멤버인 반면에, 스칼라에선 내부 클래스가 외부 객체의 경계 안에 있다. 이런 차이점을 분명히 하기 위해 그래프 데이터타입의 구현을 간단히 그려보자. - class Graph { - class Node { - var connectedNodes: List[Node] = Nil - def connectTo(node: Node): Unit = { - if (!connectedNodes.exists(node.equals)) { - connectedNodes = node :: connectedNodes - } - } - } - var nodes: List[Node] = Nil - def newNode: Node = { - val res = new Node - nodes = res :: nodes - res +```scala mdoc +class Graph { + class Node { + var connectedNodes: List[Node] = Nil + def connectTo(node: Node): Unit = { + if (!connectedNodes.exists(node.equals)) { + connectedNodes = node :: connectedNodes } } + } + var nodes: List[Node] = Nil + def newNode: Node = { + val res = new Node + nodes = res :: nodes + res + } +} +``` 이 프로그램에선 노드의 리스트로 그래프를 나타냈다. 노드는 내부 클래스 `Node`의 객체다. 각 노드는 리스트 `connectedNodes`에 저장되는 이웃의 목록을 갖고 있다. 이제 몇몇 노드를 선택하고 이에 연결된 노드를 추가하면서 점진적으로 그래프를 구축할 수 있다. -```scala mdoc +```scala mdoc:nest def graphTest: Unit = { val g = new Graph val n1 = g.newNode diff --git a/_ko/tour/self-types.md b/_ko/tour/self-types.md index ed3c8b7ad2..931a5e8312 100644 --- a/_ko/tour/self-types.md +++ b/_ko/tour/self-types.md @@ -88,16 +88,14 @@ previous-page: compound-types 다음은 클래스 `ConcreteDirectedGraph`를 사용하는 예다. -```scala mdoc -def graphTest: Unit = { - val g: Graph = new ConcreteDirectedGraph - val n1 = g.addNode - val n2 = g.addNode - val n3 = g.addNode - n1.connectWith(n2) - n2.connectWith(n3) - n1.connectWith(n3) -} -``` + def graphTest: Unit = { + val g: Graph = new ConcreteDirectedGraph + val n1 = g.addNode + val n2 = g.addNode + val n3 = g.addNode + n1.connectWith(n2) + n2.connectWith(n3) + n1.connectWith(n3) + } 윤창석, 이한욱 옮김 diff --git a/_pl/tour/inner-classes.md b/_pl/tour/inner-classes.md index 687cff4801..a97e798d36 100644 --- a/_pl/tour/inner-classes.md +++ b/_pl/tour/inner-classes.md @@ -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ą: -```scala mdoc +```scala mdoc:nest def graphTest: Unit = { val g = new Graph val n1 = g.newNode diff --git a/_pt-br/tour/inner-classes.md b/_pt-br/tour/inner-classes.md index 694d9f4a35..afaed9d896 100644 --- a/_pt-br/tour/inner-classes.md +++ b/_pt-br/tour/inner-classes.md @@ -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: -```scala mdoc +```scala mdoc:nest def graphTest: Unit = { val g = new Graph val n1 = g.newNode From a6a23b3866b505a4cfe3145d18fec1cde40125e4 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 19:07:28 +0200 Subject: [PATCH 13/16] remove some more proc syntax on main --- _de/tutorials/scala-for-java-programmers.md | 14 +++++++------- _es/tour/classes.md | 2 +- _es/tour/mixin-class-composition.md | 2 +- _es/tutorials/scala-for-java-programmers.md | 14 +++++++------- _it/tutorials/scala-for-java-programmers.md | 14 +++++++------- _ja/overviews/core/futures.md | 2 +- _ko/tour/mixin-class-composition.md | 2 +- _overviews/core/futures.md | 2 +- _pt-br/tour/classes.md | 2 +- _pt-br/tour/mixin-class-composition.md | 2 +- _sips/sips/futures-promises.md | 2 +- _zh-cn/overviews/core/futures.md | 2 +- _zh-cn/tutorials/scala-for-java-programmers.md | 14 +++++++------- _zh-tw/tutorials/scala-for-java-programmers.md | 14 +++++++------- 14 files changed, 44 insertions(+), 44 deletions(-) diff --git a/_de/tutorials/scala-for-java-programmers.md b/_de/tutorials/scala-for-java-programmers.md index e4d64108b7..9055d7caea 100644 --- a/_de/tutorials/scala-for-java-programmers.md +++ b/_de/tutorials/scala-for-java-programmers.md @@ -23,7 +23,7 @@ einfach ist, eignet es sich sehr gut, Scalas Funktionsweise zu demonstrieren, oh über die Sprache wissen muss. object HalloWelt { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { println("Hallo, Welt!") } } @@ -93,7 +93,7 @@ Klassen der Java-Pakete importieren: import java.text.DateFormat._ object FrenchDate { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val now = new Date val df = getDateInstance(LONG, Locale.FRANCE) println(df format now) @@ -183,7 +183,7 @@ einmal pro Sekunde aus. println("Die Zeit vergeht wie im Flug.") } - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { oncePerSecond(timeFlies) } } @@ -209,7 +209,7 @@ Variante des obigen Timer-Programmes verwendet eine anonyme Funktion anstatt der } } - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { oncePerSecond(() => println("Die Zeit vergeht wie im Flug.")) } } @@ -256,7 +256,7 @@ Ein Problem der obigen Methoden `re` und `im` ist, dass man, um sie zu verwenden Klammerpaar hinter ihren Namen anhängen muss: object ComplexNumbers { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val c = new Complex(1.2, 3.4) println("imaginary part: " + c.im()) } @@ -433,7 +433,7 @@ noch aus. Zu diesem Zweck soll eine `main`-Methode dienen, die den Ausdruck `(x+ Beispiel verwendet: zuerst wird der Wert in der Umgebung `{ x -> 5, y -> 7 }` berechnet und darauf die beiden partiellen Ableitungen gebildet: - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y"))) val env: Environment = { case "x" => 5 @@ -597,7 +597,7 @@ Um diese Referenz-Klasse zu verwenden, muss der generische Typ bei der Erzeugung angegeben werden. Für einen Ganzzahl-Container soll folgendes Beispiel dienen: object IntegerReference { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val cell = new Reference[Int] cell.set(13) println("Reference contains the half of " + (cell.get * 2)) diff --git a/_es/tour/classes.md b/_es/tour/classes.md index 90bd399be0..3f3939b3bc 100644 --- a/_es/tour/classes.md +++ b/_es/tour/classes.md @@ -29,7 +29,7 @@ Las clases en Scala son parametrizadas con argumentos constructores (inicializad Para instanciar una clase es necesario usar la primitiva `new`, como se muestra en el siguiente ejemplo: object Classes { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val pt = new Point(1, 2) println(pt) pt.move(10, 10) diff --git a/_es/tour/mixin-class-composition.md b/_es/tour/mixin-class-composition.md index 9221859891..cd4f497985 100644 --- a/_es/tour/mixin-class-composition.md +++ b/_es/tour/mixin-class-composition.md @@ -37,7 +37,7 @@ Aquí se muestra una clase iterador concreta, la cual retorna caracteres sucesiv Nos gustaría combinar la funcionalidad de `StringIterator` y `RichIterator` en una sola clase. Solo con herencia simple e interfaces esto es imposible, ya que ambas clases contienen implementaciones para sus miembros. Scala nos ayuda con sus _compisiciones de clases mezcladas_. Permite a los programadores reutilizar el delta de la definición de una clase, esto es, todas las nuevas definiciones que no son heredadas. Este mecanismo hace posible combinar `StringIterator` con `RichIterator`, como es hecho en el siguiente programa, el cual imprime una columna de todos los caracteres de una cadena de caracteres dada. object StringIteratorTest { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { class Iter extends StringIterator("Scala") with RichIterator val iter = new Iter iter foreach println diff --git a/_es/tutorials/scala-for-java-programmers.md b/_es/tutorials/scala-for-java-programmers.md index f4cc568f84..120d93d316 100644 --- a/_es/tutorials/scala-for-java-programmers.md +++ b/_es/tutorials/scala-for-java-programmers.md @@ -18,7 +18,7 @@ Este documento provee una rápida introducción al lenguaje Scala como también Como primer ejemplo, usaremos el programa *Hola mundo* estándar. No es muy fascinante, pero de esta manera resulta fácil demostrar el uso de herramientas de Scala sin saber demasiado acerca del lenguaje. Veamos como luce: object HolaMundo { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { println("¡Hola, mundo!") } } @@ -59,7 +59,7 @@ Las librerías de clases de Java definen clases de utilería poderosas, como `Da import java.text.DateFormat._ object FrenchDate { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val ahora = new Date val df = getDateInstance(LONG, Locale.FRANCE) println(df format ahora) @@ -116,7 +116,7 @@ En el siguiente programa, la función del temporizador se llama `unaVezPorSegund def tiempoVuela() { println("El tiempo vuela como una flecha...") } - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { unaVezPorSegundo(tiempoVuela) } } @@ -134,7 +134,7 @@ El programa anterior es fácil de entender, pero puede ser refinado aún más. P Thread sleep 1000 } } - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { unaVezPorSegundo( () => println("El tiempo vuela como una flecha...") ) @@ -167,7 +167,7 @@ El compilador no es siempre capaz de inferir los tipos como lo hace aquí, y des Un pequeño problema de los métodos `re` e `im` es que para poder llamarlos es necesario agregar un par de paréntesis vacíos después de sus nombres, como muestra el siguiente ejemplo: object NumerosComplejos { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val c = new Complejo(1.2, 3.4) println("Parte imaginaria: " + c.im()) } @@ -282,7 +282,7 @@ Esta función introduce dos nuevos conceptos relacionados al pattern matching. P No hemos explorado el completo poder del pattern matching aún, pero nos detendremos aquí para mantener este documento corto. Todavía nos queda pendiente ver cómo funcionan las dos funciones de arriba en un ejemplo real. Para ese propósito, escribamos una función main simple que realice algunas operaciones sobre la expresión `(x+x)+(7+y)`: primero computa su valor en el entorno `{ x -> 5, y -> 7 }` y después computa su derivada con respecto a `x` y después a `y`. - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val exp: Arbol = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y"))) val ent: Entonrno = { case "x" => 5 case "y" => 7 } println("Expresión: " + exp) @@ -386,7 +386,7 @@ El ejemplo anterior introduce a las variables en Scala, que no deberían requeri Para utilizar esta clase `Referencia`, uno necesita especificar qué tipo utilizar por el parámetro `T`, es decir, el tipo del elemento contenido por la referencia. Por ejemplo, para crear y utilizar una referencia que contenga un entero, podríamos escribir lo siguiente: object ReferenciaEntero { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val ref = new Referencia[Int] ref.set(13) println("La referencia tiene la mitad de " + (ref.get * 2)) diff --git a/_it/tutorials/scala-for-java-programmers.md b/_it/tutorials/scala-for-java-programmers.md index 7a60a2d6c6..5e5e7d9209 100644 --- a/_it/tutorials/scala-for-java-programmers.md +++ b/_it/tutorials/scala-for-java-programmers.md @@ -26,7 +26,7 @@ Scala senza richiedere troppe conoscenze del linguaggio stesso. Ecco come appeare il codice: object HelloWorld { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { println("Hello, world!") } } @@ -105,7 +105,7 @@ semplicemente importare le classi dei corrispondenti package Java: import java.text.DateFormat._ object FrenchDate { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val now = new Date val df = getDateInstance(LONG, Locale.FRANCE) println(df format now) @@ -204,7 +204,7 @@ frase “time flies like an arrow” ogni secondo. def timeFlies() { println("time flies like an arrow...") } - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { oncePerSecond(timeFlies) } } @@ -228,7 +228,7 @@ invece di *timeFlies* e appare come di seguito: def oncePerSecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 } } - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { oncePerSecond(() => println("time flies like an arrow...")) } @@ -283,7 +283,7 @@ necessario far seguire il nome del metodo da una coppia di parentesi tonde vuote, come mostrato nel codice seguente: object ComplexNumbers { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val c = new Complex(1.2, 3.4) println("imaginary part: " + c.im()) } @@ -499,7 +499,7 @@ sull’espressione `(x+x)+(7+y)`: prima calcola il suo valore nell’environment `{ x -> 5, y -> 7 }`, dopo calcola la derivata relativa ad `x` e poi ad `y`. - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y"))) val env: Environment = { case "x" => 5 case "y" => 7 } println("Expression: " + exp) @@ -678,7 +678,7 @@ per creare ed usare una cella che contiene un intero si potrebbe scrivere il seguente codice: object IntegerReference { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val cell = new Reference[Int] cell.set(13) println("Reference contains the half of " + (cell.get * 2)) diff --git a/_ja/overviews/core/futures.md b/_ja/overviews/core/futures.md index d644886a12..8796c37b4d 100644 --- a/_ja/overviews/core/futures.md +++ b/_ja/overviews/core/futures.md @@ -500,7 +500,7 @@ Future の結果に対してブロックする方法を以下に具体例で説 import scala.concurrent._ import scala.concurrent.duration._ - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val rateQuote = Future { connection.getCurrentValue(USD) } diff --git a/_ko/tour/mixin-class-composition.md b/_ko/tour/mixin-class-composition.md index 122d1051a4..0ba4ef49bf 100644 --- a/_ko/tour/mixin-class-composition.md +++ b/_ko/tour/mixin-class-composition.md @@ -36,7 +36,7 @@ _단일 상속_ 만을 지원하는 여러 언어와는 달리, 스칼라는 더 `StringIterator`와 `RichIterator`를 하나의 클래스로 합치고 싶다면 어떻게 할까. 두 클래스 모두는 코드가 포함된 멤버 구현을 담고 있기 때문에 단일 상속과 인터페이스 만으론 불가능한 일이다. 스칼라는 _믹스인 클래스 컴포지션_ 으로 이런 상황을 해결해준다. 프로그래머는 이를 사용해 클래스 정의에서 변경된 부분을 재사용할 수 있다. 이 기법은 주어진 문자열에 포함된 모든 캐릭터를 한 줄로 출력해주는 다음의 테스트 프로그램에서와 같이, `StringIterator`와 `RichIterator`를 통합할 수 있도록 해준다. object StringIteratorTest { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { class Iter extends StringIterator("Scala") with RichIterator val iter = new Iter iter foreach println diff --git a/_overviews/core/futures.md b/_overviews/core/futures.md index 6b9e6bae4a..9704cd57af 100644 --- a/_overviews/core/futures.md +++ b/_overviews/core/futures.md @@ -1052,7 +1052,7 @@ Here is an example of how to block on the result of a future: import scala.concurrent.duration._ object awaitPurchase { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val rateQuote = Future { connection.getCurrentValue(USD) } diff --git a/_pt-br/tour/classes.md b/_pt-br/tour/classes.md index 26a49fc55e..4683128312 100644 --- a/_pt-br/tour/classes.md +++ b/_pt-br/tour/classes.md @@ -33,7 +33,7 @@ Classes são instânciadas com a primitiva `new`, por exemplo: ```scala mdoc object Classes { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val pt = new Ponto(1, 2) println(pt) pt.move(10, 10) diff --git a/_pt-br/tour/mixin-class-composition.md b/_pt-br/tour/mixin-class-composition.md index 80002a731a..3d0226a909 100644 --- a/_pt-br/tour/mixin-class-composition.md +++ b/_pt-br/tour/mixin-class-composition.md @@ -43,7 +43,7 @@ Poderíamos combinar a funcionalidade de `StringIterator` e `RichIterator` em um ```scala mdoc object StringIteratorTest { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { class Iter extends StringIterator("Scala") with RichIterator val iter = new Iter iter foreach println diff --git a/_sips/sips/futures-promises.md b/_sips/sips/futures-promises.md index f69ac68c92..a35156c03a 100644 --- a/_sips/sips/futures-promises.md +++ b/_sips/sips/futures-promises.md @@ -461,7 +461,7 @@ Here is an example of how to block on the result of a future: import scala.concurrent._ - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val rateQuote = Future { connection.getCurrentValue(USD) } diff --git a/_zh-cn/overviews/core/futures.md b/_zh-cn/overviews/core/futures.md index 26da10969d..c37b66efe5 100644 --- a/_zh-cn/overviews/core/futures.md +++ b/_zh-cn/overviews/core/futures.md @@ -340,7 +340,7 @@ fallbackTo组合器生成的future对象可以在该原future成功完成计算 import scala.concurrent._ import scala.concurrent.duration._ - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val rateQuote = Future { connection.getCurrentValue(USD) } diff --git a/_zh-cn/tutorials/scala-for-java-programmers.md b/_zh-cn/tutorials/scala-for-java-programmers.md index 00559b596d..a3327a1963 100644 --- a/_zh-cn/tutorials/scala-for-java-programmers.md +++ b/_zh-cn/tutorials/scala-for-java-programmers.md @@ -18,7 +18,7 @@ Lightsing 译 这里用标准的 *Hello world* 程序作为第一个例子。虽然它很无趣,但让我们可以用少量语言特质来演示 Scala 工具。程序如下: object HelloWorld { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { println("Hello, world!") } } @@ -60,7 +60,7 @@ Java 的标准函数库定义了一些有用的工具类,如 `Date` 跟 `DateF import java.text.DateFormat._ object FrenchDate { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val now = new Date val df = getDateInstance(LONG, Locale.FRANCE) println(df format now) @@ -114,7 +114,7 @@ Scala 中的函数也是对象,所以将函数当做对象传递、把它们 def timeFlies() { println("time flies like an arrow...") } - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { oncePerSecond(timeFlies) } } @@ -129,7 +129,7 @@ Scala 中的函数也是对象,所以将函数当做对象传递、把它们 def oncePerSecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 } } - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { oncePerSecond(() => println("time flies like an arrow...")) } @@ -157,7 +157,7 @@ Scala 中的函数也是对象,所以将函数当做对象传递、把它们 函数 `re`、`im` 有个小问题,为了调用函数,我们必须在函数名称后面加上一对空括号,如这个例子: object ComplexNumbers { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val c = new Complex(1.2, 3.4) println("imaginary part: " + c.im()) } @@ -261,7 +261,7 @@ Java 中我们会将这个树用一个抽象父类表示,然后每种节点跟 我们还没有探讨完模式匹配的全部功能,不过为了让这份文件保持简短,先就此打住。我们还是希望能看到这两个函数在真正的示例如何作用。因此让我们写一个简单的 `main` 函数,对表达式 `(x+x)+(7+y)` 做一些操作:先在环境 `{ x -> 5, y -> 7 }` 下计算结果,然后在对 `x` 接着对 `y` 取导数。 - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y"))) val env: Environment = { case "x" => 5 case "y" => 7 } println("Expression: " + exp) @@ -361,7 +361,7 @@ Scala 借由可定义泛型类 (跟函数) 来解决这问题。让我们借由 为了使用 `Reference` 类型,我们必须指定 `T`,也就是这容器所包容的元素类型。举例来说,创造并使用该容器来容纳整数,我们可以这样写: object IntegerReference { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val cell = new Reference[Int] cell.set(13) println("Reference contains the half of " + (cell.get * 2)) diff --git a/_zh-tw/tutorials/scala-for-java-programmers.md b/_zh-tw/tutorials/scala-for-java-programmers.md index d9b4bcd4d0..333744ecea 100755 --- a/_zh-tw/tutorials/scala-for-java-programmers.md +++ b/_zh-tw/tutorials/scala-for-java-programmers.md @@ -18,7 +18,7 @@ Chikei Lee 譯 這邊用標準的 *Hello world* 程式作為第一個例子。雖然它很無趣,可是這讓我們在僅用少量語言特性下演示 Scala 工具。程式如下: object HelloWorld { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { println("Hello, world!") } } @@ -60,7 +60,7 @@ Java 的標準函式庫定義了一些有用的工具類別,如 `Date` 跟 `Da import java.text.DateFormat._ object FrenchDate { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val now = new Date val df = getDateInstance(LONG, Locale.FRANCE) println(df format now) @@ -114,7 +114,7 @@ Scala 是一個純粹的物件導向語言,這句話的意思是說,*所有 def timeFlies() { println("time flies like an arrow...") } - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { oncePerSecond(timeFlies) } } @@ -129,7 +129,7 @@ Scala 是一個純粹的物件導向語言,這句話的意思是說,*所有 def oncePerSecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 } } - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { oncePerSecond(() => println("time flies like an arrow...")) } @@ -157,7 +157,7 @@ Scala 是一個純粹的物件導向語言,這句話的意思是說,*所有 函式 `re`、`im` 有個小問題,為了呼叫函式,我們必須在函式名稱後面加上一對空括號,如這個例子: object ComplexNumbers { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val c = new Complex(1.2, 3.4) println("imaginary part: " + c.im()) } @@ -261,7 +261,7 @@ Java 中我們會將這個樹用一個抽象母類別表示,然後每種節點 我們還沒有探討完模式匹配的全部功能,不過為了讓這份文件保持簡短,先就此打住。我們還是希望能看到這兩個函式在真正的範例如何作用。因此讓我們寫一個簡單的 `main` 函數,對表示式 `(x+x)+(7+y)` 做一些操作:先在環境 `{ x -> 5, y -> 7 }` 下計算結果,然後在對 `x` 接著對 `y` 取導數。 - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y"))) val env: Environment = { case "x" => 5 case "y" => 7 } println("Expression: " + exp) @@ -361,7 +361,7 @@ Scala 藉由可定義泛型類別 (跟函式) 來解決這問題。讓我們藉 為了使用 `Reference` 類型,我們必須指定 `T`,也就是這容器所包容的元素型別。舉例來說,創造並使用該容器來容納整數,我們可以這樣寫: object IntegerReference { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val cell = new Reference[Int] cell.set(13) println("Reference contains the half of " + (cell.get * 2)) From f432dceec9db65469691229d7876d2fe307062a3 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 19:10:06 +0200 Subject: [PATCH 14/16] remove some more proc syntax on foreach --- _ba/tour/mixin-class-composition.md | 14 +++++++------- _es/tour/mixin-class-composition.md | 2 +- _ko/tour/mixin-class-composition.md | 2 +- _pt-br/tour/mixin-class-composition.md | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/_ba/tour/mixin-class-composition.md b/_ba/tour/mixin-class-composition.md index a38c2ba2e1..a8216abfb6 100644 --- a/_ba/tour/mixin-class-composition.md +++ b/_ba/tour/mixin-class-composition.md @@ -29,11 +29,11 @@ val d = new D d.message // I'm an instance of class B d.loudMessage // I'M AN INSTANCE OF CLASS B ``` -Klasa `D` je nadklasa od `B` i mixina `C`. +Klasa `D` je nadklasa od `B` i mixina `C`. Klase mogu imati samo jednu nadklasu alid mogu imati više mixina (koristeći ključne riječi `extends` i `with` respektivno). Mixini i nadklasa mogu imati isti nadtip. Pogledajmo sada zanimljiviji primjer počevši od apstraktne klase: - + ```scala mdoc abstract class AbsIterator { type T @@ -41,7 +41,7 @@ abstract class AbsIterator { def next(): T } ``` - + Klasa ima apstraktni tip `T` i standardne metode iteratora. Dalje, implementiraćemo konkretnu klasu (svi apstraktni članovi `T`, `hasNext`, i `next` imaju implementacije): @@ -59,9 +59,9 @@ class StringIterator(s: String) extends AbsIterator { ``` `StringIterator` prima `String` i može se koristiti za iteraciju nad `String`om (npr. da vidimo da li sadrži određeni karakter). - + trait RichIterator extends AbsIterator { - def foreach(f: T => Unit) { while (hasNext) f(next()) } + def foreach(f: T => Unit): Unit = { while (hasNext) f(next()) } } Kreirajmo sada trejt koji također nasljeđuje `AbsIterator`. @@ -74,7 +74,7 @@ trait RichIterator extends AbsIterator { Pošto je `RichIterator` trejt, on ne mora implementirati apstraktne članove `AbsIterator`a. -Željeli bismo iskombinirati funkcionalnosti `StringIterator`a i `RichIterator`a u jednoj klasi. +Željeli bismo iskombinirati funkcionalnosti `StringIterator`a i `RichIterator`a u jednoj klasi. ```scala mdoc object StringIteratorTest extends App { @@ -83,7 +83,7 @@ object StringIteratorTest extends App { iter foreach println } ``` - + Nova klasa `Iter` ima `StringIterator` kao nadklasu i `RichIterator` kao mixin. S jednostrukim nasljeđivanjem ne bismo mogli postići ovaj nivo fleksibilnosti. diff --git a/_es/tour/mixin-class-composition.md b/_es/tour/mixin-class-composition.md index cd4f497985..bd53274158 100644 --- a/_es/tour/mixin-class-composition.md +++ b/_es/tour/mixin-class-composition.md @@ -22,7 +22,7 @@ A diferencia de lenguajes que solo soportan _herencia simple_, Scala tiene una n A continuación, considere una clase mezcla la cual extiende `AbsIterator` con un método `foreach` el cual aplica una función dada a cada elemento retornado por el iterador. Para definir una clase que puede usarse como una clase mezcla usamos la palabra clave `trait`. trait RichIterator extends AbsIterator { - def foreach(f: T => Unit) { while (hasNext) f(next()) } + def foreach(f: T => Unit): Unit = { while (hasNext) f(next()) } } Aquí se muestra una clase iterador concreta, la cual retorna caracteres sucesivos de una cadena de caracteres dada: diff --git a/_ko/tour/mixin-class-composition.md b/_ko/tour/mixin-class-composition.md index 0ba4ef49bf..94f21d2244 100644 --- a/_ko/tour/mixin-class-composition.md +++ b/_ko/tour/mixin-class-composition.md @@ -21,7 +21,7 @@ _단일 상속_ 만을 지원하는 여러 언어와는 달리, 스칼라는 더 이어서, 이터레이터가 반환하는 모든 항목에 주어진 함수를 적용해주는 `foreach` 메소드로 `AbsIterator`를 확장한 믹스인 클래스를 살펴보자. 믹스인으로 사용할 수 있는 클래스를 정의하기 위해선 `trait`이란 키워드를 사용한다. trait RichIterator extends AbsIterator { - def foreach(f: T => Unit) { while (hasNext) f(next()) } + def foreach(f: T => Unit): Unit = { while (hasNext) f(next()) } } 다음은 주어진 문자열의 캐릭터를 차례로 반환해주는 콘크리트 이터레이터 클래스다. diff --git a/_pt-br/tour/mixin-class-composition.md b/_pt-br/tour/mixin-class-composition.md index 3d0226a909..e317924e0b 100644 --- a/_pt-br/tour/mixin-class-composition.md +++ b/_pt-br/tour/mixin-class-composition.md @@ -24,7 +24,7 @@ A seguir, considere a classe mixin que estende `AbsIterator` com um método `for ```scala mdoc trait RichIterator extends AbsIterator { - def foreach(f: T => Unit) { while (hasNext) f(next()) } + def foreach(f: T => Unit): Unit = { while (hasNext) f(next()) } } ``` From 053308da47c03834c1403545cdfb034fb3f847ab Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 19:13:52 +0200 Subject: [PATCH 15/16] remove more app wrappers --- _tour/automatic-closures.md | 48 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/_tour/automatic-closures.md b/_tour/automatic-closures.md index 4e817b4dca..b2fd0f3983 100644 --- a/_tour/automatic-closures.md +++ b/_tour/automatic-closures.md @@ -10,18 +10,18 @@ Scala allows parameterless function names as parameters of methods. When such a The following code demonstrates this mechanism: - object TargetTest1 extends Application { - def whileLoop(cond: => Boolean)(body: => Unit): Unit = - if (cond) { - body - whileLoop(cond)(body) - } - var i = 10 - whileLoop (i > 0) { - println(i) - i -= 1 - } - } +```scala mdoc +def whileLoop(cond: => Boolean)(body: => Unit): Unit = + if (cond) { + body + whileLoop(cond)(body) + } +var i = 10 +whileLoop (i > 0) { + println(i) + i -= 1 +} +``` The function whileLoop takes two parameters `cond` and `body`. When the function is applied, the actual parameters do not get evaluated. But whenever the formal parameters are used in the body of `whileLoop`, the implicitly created nullary functions will be evaluated instead. Thus, our method `whileLoop` implements a Java-like while-loop with a recursive implementation scheme. @@ -30,21 +30,19 @@ We can combine the use of [infix/postfix operators](operators.html) with this me Here is the implementation of a loop-unless statement: ```scala mdoc -object TargetTest2 extends Application { - def loop(body: => Unit): LoopUnlessCond = - new LoopUnlessCond(body) - protected class LoopUnlessCond(body: => Unit) { - def unless(cond: => Boolean): Unit = { - body - if (!cond) unless(cond) - } +def loop(body: => Unit): LoopUnlessCond = + new LoopUnlessCond(body) +protected class LoopUnlessCond(body: => Unit) { + def unless(cond: => Boolean): Unit = { + body + if (!cond) unless(cond) } - var i = 10 - loop { - println("i = " + i) - i -= 1 - } unless (i == 0) } +var i = 10 +loop { + println("i = " + i) + i -= 1 +} unless (i == 0) ``` The `loop` function just accepts a body of a loop and returns an instance of class `LoopUnlessCond` (which encapsulates this body object). Note that the body didn't get evaluated yet. Class `LoopUnlessCond` has a method `unless` which we can use as a *infix operator*. This way, we achieve a quite natural syntax for our new loop: `loop { < stats > } unless ( < cond > )`. From 0016b577bf0c540e43339cdbc76762e831f18fe4 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 16 Sep 2022 19:27:41 +0200 Subject: [PATCH 16/16] reset mdoc --- _pl/tour/automatic-closures.md | 44 ++++++++++++++----------------- _pt-br/tour/automatic-closures.md | 44 ++++++++++++++----------------- _tour/automatic-closures.md | 2 +- 3 files changed, 41 insertions(+), 49 deletions(-) diff --git a/_pl/tour/automatic-closures.md b/_pl/tour/automatic-closures.md index 2b50e803e6..8251a6be35 100644 --- a/_pl/tour/automatic-closures.md +++ b/_pl/tour/automatic-closures.md @@ -14,17 +14,15 @@ Scala pozwala na przekazywanie funkcji bezparametrycznych jako argumenty dla met Poniższy kod demonstruje działanie tego mechanizmu: ```scala mdoc -object TargetTest1 extends App { - def whileLoop(cond: => Boolean)(body: => Unit): Unit = - if (cond) { - body - whileLoop(cond)(body) - } - var i = 10 - whileLoop (i > 0) { - println(i) - i -= 1 +def whileLoop(cond: => Boolean)(body: => Unit): Unit = + if (cond) { + body + whileLoop(cond)(body) } +var i = 10 +whileLoop (i > 0) { + println(i) + i -= 1 } ``` @@ -34,22 +32,20 @@ Możemy połączyć ze sobą wykorzystanie [operatorów infiksowych/postfiksowyc Oto implementacja pętli w stylu wykonaj-dopóki: -```scala mdoc -object TargetTest2 extends App { - def loop(body: => Unit): LoopUnlessCond = - new LoopUnlessCond(body) - protected class LoopUnlessCond(body: => Unit) { - def unless(cond: => Boolean): Unit = { - body - if (!cond) unless(cond) - } +```scala mdoc:reset +def loop(body: => Unit): LoopUnlessCond = + new LoopUnlessCond(body) +protected class LoopUnlessCond(body: => Unit) { + def unless(cond: => Boolean): Unit = { + body + if (!cond) unless(cond) } - var i = 10 - loop { - println("i = " + i) - i -= 1 - } unless (i == 0) } +var i = 10 +loop { + println("i = " + i) + i -= 1 +} unless (i == 0) ``` Funkcja `loop` przyjmuje ciało pętli oraz zwraca instancję klasy `LoopUnlessCond` (która enkapsuluje to ciało). Warto zwrócić uwagę, że ciało tej funkcji nie zostało jeszcze ewaluowane. Klasa `LoopUnlessCond` posiada metodę `unless`, którą możemy wykorzystać jako *operator infiksowy*. W ten sposób uzyskaliśmy całkiem naturalną składnię dla naszej nowej pętli: `loop { < stats > } unless ( < cond > )`. diff --git a/_pt-br/tour/automatic-closures.md b/_pt-br/tour/automatic-closures.md index 81084cd575..dfa5b9dd12 100644 --- a/_pt-br/tour/automatic-closures.md +++ b/_pt-br/tour/automatic-closures.md @@ -16,17 +16,15 @@ Scala permite funções sem parâmetros como parâmetros de métodos. Quando um O código a seguir demonstra esse mecanismo: ```scala mdoc -object TargetTest1 extends App { - def whileLoop(cond: => Boolean)(body: => Unit): Unit = - if (cond) { - body - whileLoop(cond)(body) - } - var i = 10 - whileLoop (i > 0) { - println(i) - i -= 1 +def whileLoop(cond: => Boolean)(body: => Unit): Unit = + if (cond) { + body + whileLoop(cond)(body) } +var i = 10 +whileLoop (i > 0) { + println(i) + i -= 1 } ``` @@ -36,22 +34,20 @@ 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: -```scala mdoc -object TargetTest2 extends App { - def loop(body: => Unit): LoopUnlessCond = - new LoopUnlessCond(body) - protected class LoopUnlessCond(body: => Unit) { - def unless(cond: => Boolean): Unit = { - body - if (!cond) unless(cond) - } +```scala mdoc:reset +def loop(body: => Unit): LoopUnlessCond = + new LoopUnlessCond(body) +protected class LoopUnlessCond(body: => Unit) { + def unless(cond: => Boolean): Unit = { + body + if (!cond) unless(cond) } - var i = 10 - loop { - println("i = " + i) - i -= 1 - } unless (i == 0) } +var i = 10 +loop { + println("i = " + i) + i -= 1 +} unless (i == 0) ``` A função `loop` aceita apenas um corpo e retorna uma instância da classe` LoopUnlessCond` (que encapsula este objeto de corpo). Note que o corpo ainda não foi avaliado. A classe `LoopUnlessCond` tem um método `unless` que podemos usar como um *operador infix*. Dessa forma, obtemos uma sintaxe bastante natural para nosso novo loop: `loop { } unless ( )`. diff --git a/_tour/automatic-closures.md b/_tour/automatic-closures.md index b2fd0f3983..2a3d889d35 100644 --- a/_tour/automatic-closures.md +++ b/_tour/automatic-closures.md @@ -29,7 +29,7 @@ We can combine the use of [infix/postfix operators](operators.html) with this me Here is the implementation of a loop-unless statement: -```scala mdoc +```scala mdoc:reset def loop(body: => Unit): LoopUnlessCond = new LoopUnlessCond(body) protected class LoopUnlessCond(body: => Unit) {