From 59499abb797ff130d8e555422c764020e2932b86 Mon Sep 17 00:00:00 2001 From: Pablo Arranz Ropero Date: Sat, 1 Jun 2019 12:36:15 +0200 Subject: translating scala --- es-es/scala.html.markdown | 754 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 754 insertions(+) create mode 100644 es-es/scala.html.markdown (limited to 'es-es') diff --git a/es-es/scala.html.markdown b/es-es/scala.html.markdown new file mode 100644 index 00000000..319d5f9d --- /dev/null +++ b/es-es/scala.html.markdown @@ -0,0 +1,754 @@ +--- +language: Scala +filename: learnscala-es.scala +contributors: + - ["George Petrov", "http://github.com/petrovg"] + - ["Dominic Bou-Samra", "http://dbousamra.github.com"] + - ["Geoff Liu", "http://geoffliu.me"] + - ["Ha-Duong Nguyen", "http://reference-error.org"] +translators: + - ["Pablo Arranz Ropero", "http://arranzropablo.com"] +lang: es-es +--- + +Scala - El lenguaje escalable + +```scala + +///////////////////////////////////////////////// +// 0. Básicos +///////////////////////////////////////////////// +/* + Configurar Scala: + + 1) Descarga Scala - http://www.scala-lang.org/downloads + 2) Unzip/untar a tu carpeta elegida y pon la subcarpeta bin en tu variable de entorno `PATH` +*/ + +/* + Prueba REPL + + Scala tiene una herramienta llamada REPL (Read-Eval-Print Loop, en español: Bucle de lectura-evaluación-impresión) que es analogo a interpretes de la linea de comandos en muchos otros lenguajes. + Puedes escribir cualquier expresión en Scala y el resultado será evaluado e impreso. + + REPL es una herramienta muy práctica para testear y verificar código. + Puedes usarla mientras lees este tutorial para explorar conceptos por tu cuenta. +*/ + +// Inicia Scala REPL ejecutando `scala` en tu terminal. Deberías ver: +$ scala +scala> + +// Por defecto cada expresión que escribes es guardada como un nuevo valor numerado: +scala> 2 + 2 +res0: Int = 4 + +// Los valores por defecto pueden ser reusados. Fíjate en el tipo del valor mostrado en el resultado... +scala> res0 + 2 +res1: Int = 6 + +// Scala es un lenguaje fuertemente tipado. Puedes usar REPL para comprobar el tipo sin evaluar una expresión. +scala> :type (true, 2.0) +(Boolean, Double) + +// Las sesiones REPL pueden ser guardadas +scala> :save /sites/repl-test.scala + +// Se pueden cargar archivos en REPL +scala> :load /sites/repl-test.scala +Loading /sites/repl-test.scala... +res2: Int = 4 +res3: Int = 6 + +// Puedes buscar en tu historial reciente +scala> :h? +1 2 + 2 +2 res0 + 2 +3 :save /sites/repl-test.scala +4 :load /sites/repl-test.scala +5 :h? + +// Ahora que sabes como jugar, aprendamos un poco de Scala... + +///////////////////////////////////////////////// +// 1. Básicos +///////////////////////////////////////////////// + +// Los comentarios de una linea comienzan con dos barras inclinadas + +/* + Los comentarios de varias lineas, como ya has visto arriba, se hacen de esta manera. +*/ + +// Así imprimimos forzando una nueva linea en la siguiente impresión +println("Hola mundo!") +println(10) +// Hola mundo! +// 10 + +// Así imprimimos sin forzar una nueva linea en la siguiente impresión +print("Hola mundo") +print(10) +// Hola mundo10 + +// Para declarar valores usamos var o val. +// Valores decalrados con val son inmutables, mientras que los declarados con var son mutables. +// La inmutabilidad es algo bueno. +val x = 10 // x es 10 +x = 20 // error: reassignment to val +var y = 10 +y = 20 // y es 20 + +/* + Scala is a statically typed language, yet note that in the above declarations, + we did not specify a type. This is due to a language feature called type + inference. In most cases, Scala compiler can guess what the type of a variable + is, so you don't have to type it every time. We can explicitly declare the + type of a variable like so: +*/ +val z: Int = 10 +val a: Double = 1.0 + +// Notice automatic conversion from Int to Double, result is 10.0, not 10 +val b: Double = 10 + +// Boolean values +true +false + +// Boolean operations +!true // false +!false // true +true == false // false +10 > 5 // true + +// Math is as per usual +1 + 1 // 2 +2 - 1 // 1 +5 * 3 // 15 +6 / 2 // 3 +6 / 4 // 1 +6.0 / 4 // 1.5 +6 / 4.0 // 1.5 + + +// Evaluating an expression in the REPL gives you the type and value of the result + +1 + 7 + +/* The above line results in: + + scala> 1 + 7 + res29: Int = 8 + + This means the result of evaluating 1 + 7 is an object of type Int with a + value of 8 + + Note that "res29" is a sequentially generated variable name to store the + results of the expressions you typed, your output may differ. +*/ + +"Scala strings are surrounded by double quotes" +'a' // A Scala Char +// 'Single quote strings don't exist' <= This causes an error + +// Strings have the usual Java methods defined on them +"hello world".length +"hello world".substring(2, 6) +"hello world".replace("C", "3") + +// They also have some extra Scala methods. See also: scala.collection.immutable.StringOps +"hello world".take(5) +"hello world".drop(5) + +// String interpolation: notice the prefix "s" +val n = 45 +s"We have $n apples" // => "We have 45 apples" + +// Expressions inside interpolated strings are also possible +val a = Array(11, 9, 6) +s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old." +s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples." +s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4" + +// Formatting with interpolated strings with the prefix "f" +f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25" +f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454" + +// Raw strings, ignoring special characters. +raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r." + +// Some characters need to be "escaped", e.g. a double quote inside a string: +"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown"" + +// Triple double-quotes let strings span multiple rows and contain quotes +val html = """
+

Press belo', Joe

+ +
""" + + +///////////////////////////////////////////////// +// 2. Functions +///////////////////////////////////////////////// + +// Functions are defined like so: +// +// def functionName(args...): ReturnType = { body... } +// +// If you come from more traditional languages, notice the omission of the +// return keyword. In Scala, the last expression in the function block is the +// return value. +def sumOfSquares(x: Int, y: Int): Int = { + val x2 = x * x + val y2 = y * y + x2 + y2 +} + +// The { } can be omitted if the function body is a single expression: +def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y + +// Syntax for calling functions is familiar: +sumOfSquares(3, 4) // => 25 + +// You can use parameters names to specify them in different order +def subtract(x: Int, y: Int): Int = x - y + +subtract(10, 3) // => 7 +subtract(y=10, x=3) // => -7 + +// In most cases (with recursive functions the most notable exception), function +// return type can be omitted, and the same type inference we saw with variables +// will work with function return values: +def sq(x: Int) = x * x // Compiler can guess return type is Int + +// Functions can have default parameters: +def addWithDefault(x: Int, y: Int = 5) = x + y +addWithDefault(1, 2) // => 3 +addWithDefault(1) // => 6 + + +// Anonymous functions look like this: +(x: Int) => x * x + +// Unlike defs, even the input type of anonymous functions can be omitted if the +// context makes it clear. Notice the type "Int => Int" which means a function +// that takes Int and returns Int. +val sq: Int => Int = x => x * x + +// Anonymous functions can be called as usual: +sq(10) // => 100 + +// If each argument in your anonymous function is +// used only once, Scala gives you an even shorter way to define them. These +// anonymous functions turn out to be extremely common, as will be obvious in +// the data structure section. +val addOne: Int => Int = _ + 1 +val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3) + +addOne(5) // => 6 +weirdSum(2, 4) // => 16 + + +// The return keyword exists in Scala, but it only returns from the inner-most +// def that surrounds it. +// WARNING: Using return in Scala is error-prone and should be avoided. +// It has no effect on anonymous functions. For example: +def foo(x: Int): Int = { + val anonFunc: Int => Int = { z => + if (z > 5) + return z // This line makes z the return value of foo! + else + z + 2 // This line is the return value of anonFunc + } + anonFunc(x) // This line is the return value of foo +} + + +///////////////////////////////////////////////// +// 3. Flow Control +///////////////////////////////////////////////// + +1 to 5 +val r = 1 to 5 +r.foreach(println) + +r foreach println +// NB: Scala is quite lenient when it comes to dots and brackets - study the +// rules separately. This helps write DSLs and APIs that read like English + +// Why doesn't `println` need any parameters here? +// Stay tuned for first-class functions in the Functional Programming section below! +(5 to 1 by -1) foreach (println) + +// A while loop +var i = 0 +while (i < 10) { println("i " + i); i += 1 } + +while (i < 10) { println("i " + i); i += 1 } // Yes, again. What happened? Why? + +i // Show the value of i. Note that while is a loop in the classical sense - + // it executes sequentially while changing the loop variable. while is very + // fast, but using the combinators and comprehensions above is easier + // to understand and parallelize + +// A do-while loop +i = 0 +do { + println("i is still less than 10") + i += 1 +} while (i < 10) + +// Recursion is the idiomatic way of repeating an action in Scala (as in most +// other functional languages). +// Recursive functions need an explicit return type, the compiler can't infer it. +// Here it's Unit, which is analagous to a `void` return type in Java +def showNumbersInRange(a: Int, b: Int): Unit = { + print(a) + if (a < b) + showNumbersInRange(a + 1, b) +} +showNumbersInRange(1, 14) + + +// Conditionals + +val x = 10 + +if (x == 1) println("yeah") +if (x == 10) println("yeah") +if (x == 11) println("yeah") +if (x == 11) println("yeah") else println("nay") + +println(if (x == 10) "yeah" else "nope") +val text = if (x == 10) "yeah" else "nope" + + +///////////////////////////////////////////////// +// 4. Data Structures +///////////////////////////////////////////////// + +val a = Array(1, 2, 3, 5, 8, 13) +a(0) // Int = 1 +a(3) // Int = 5 +a(21) // Throws an exception + +val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo") +m("fork") // java.lang.String = tenedor +m("spoon") // java.lang.String = cuchara +m("bottle") // Throws an exception + +val safeM = m.withDefaultValue("no lo se") +safeM("bottle") // java.lang.String = no lo se + +val s = Set(1, 3, 7) +s(0) // Boolean = false +s(1) // Boolean = true + +/* Look up the documentation of map here - + * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map + * and make sure you can read it + */ + + +// Tuples + +(1, 2) + +(4, 3, 2) + +(1, 2, "three") + +(a, 2, "three") + +// Why have this? +val divideInts = (x: Int, y: Int) => (x / y, x % y) + +// The function divideInts gives you the result and the remainder +divideInts(10, 3) // (Int, Int) = (3,1) + +// To access the elements of a tuple, use _._n where n is the 1-based index of +// the element +val d = divideInts(10, 3) // (Int, Int) = (3,1) + +d._1 // Int = 3 +d._2 // Int = 1 + +// Alternatively you can do multiple-variable assignment to tuple, which is more +// convenient and readable in many cases +val (div, mod) = divideInts(10, 3) + +div // Int = 3 +mod // Int = 1 + + +///////////////////////////////////////////////// +// 5. Object Oriented Programming +///////////////////////////////////////////////// + +/* + Aside: Everything we've done so far in this tutorial has been simple + expressions (values, functions, etc). These expressions are fine to type into + the command-line interpreter for quick tests, but they cannot exist by + themselves in a Scala file. For example, you cannot have just "val x = 5" in + a Scala file. Instead, the only top-level constructs allowed in Scala are: + + - objects + - classes + - case classes + - traits + + And now we will explain what these are. +*/ + +// classes are similar to classes in other languages. Constructor arguments are +// declared after the class name, and initialization is done in the class body. +class Dog(br: String) { + // Constructor code here + var breed: String = br + + // Define a method called bark, returning a String + def bark = "Woof, woof!" + + // Values and methods are assumed public. "protected" and "private" keywords + // are also available. + private def sleep(hours: Int) = + println(s"I'm sleeping for $hours hours") + + // Abstract methods are simply methods with no body. If we uncomment the + // def line below, class Dog would need to be declared abstract like so: + // abstract class Dog(...) { ... } + // def chaseAfter(what: String): String +} + +val mydog = new Dog("greyhound") +println(mydog.breed) // => "greyhound" +println(mydog.bark) // => "Woof, woof!" + + +// The "object" keyword creates a type AND a singleton instance of it. It is +// common for Scala classes to have a "companion object", where the per-instance +// behavior is captured in the classes themselves, but behavior related to all +// instance of that class go in objects. The difference is similar to class +// methods vs static methods in other languages. Note that objects and classes +// can have the same name. +object Dog { + def allKnownBreeds = List("pitbull", "shepherd", "retriever") + def createDog(breed: String) = new Dog(breed) +} + + +// Case classes are classes that have extra functionality built in. A common +// question for Scala beginners is when to use classes and when to use case +// classes. The line is quite fuzzy, but in general, classes tend to focus on +// encapsulation, polymorphism, and behavior. The values in these classes tend +// to be private, and only methods are exposed. The primary purpose of case +// classes is to hold immutable data. They often have few methods, and the +// methods rarely have side-effects. +case class Person(name: String, phoneNumber: String) + +// Create a new instance. Note cases classes don't need "new" +val george = Person("George", "1234") +val kate = Person("Kate", "4567") + +// With case classes, you get a few perks for free, like getters: +george.phoneNumber // => "1234" + +// Per field equality (no need to override .equals) +Person("George", "1234") == Person("Kate", "1236") // => false + +// Easy way to copy +// otherGeorge == Person("George", "9876") +val otherGeorge = george.copy(phoneNumber = "9876") + +// And many others. Case classes also get pattern matching for free, see below. + +// Traits +// Similar to Java interfaces, traits define an object type and method +// signatures. Scala allows partial implementation of those methods. +// Constructor parameters are not allowed. Traits can inherit from other +// traits or classes without parameters. + +trait Dog { + def breed: String + def color: String + def bark: Boolean = true + def bite: Boolean +} +class SaintBernard extends Dog { + val breed = "Saint Bernard" + val color = "brown" + def bite = false +} + +scala> b +res0: SaintBernard = SaintBernard@3e57cd70 +scala> b.breed +res1: String = Saint Bernard +scala> b.bark +res2: Boolean = true +scala> b.bite +res3: Boolean = false + +// A trait can also be used as Mixin. The class "extends" the first trait, +// but the keyword "with" can add additional traits. + +trait Bark { + def bark: String = "Woof" +} +trait Dog { + def breed: String + def color: String +} +class SaintBernard extends Dog with Bark { + val breed = "Saint Bernard" + val color = "brown" +} + +scala> val b = new SaintBernard +b: SaintBernard = SaintBernard@7b69c6ba +scala> b.bark +res0: String = Woof + + +///////////////////////////////////////////////// +// 6. Pattern Matching +///////////////////////////////////////////////// + +// Pattern matching is a powerful and commonly used feature in Scala. Here's how +// you pattern match a case class. NB: Unlike other languages, Scala cases do +// not need breaks, fall-through does not happen. + +def matchPerson(person: Person): String = person match { + // Then you specify the patterns: + case Person("George", number) => "We found George! His number is " + number + case Person("Kate", number) => "We found Kate! Her number is " + number + case Person(name, number) => "We matched someone : " + name + ", phone : " + number +} + +// Regular expressions are also built in. +// Create a regex with the `r` method on a string: +val email = "(.*)@(.*)".r + +// Pattern matching might look familiar to the switch statements in the C family +// of languages, but this is much more powerful. In Scala, you can match much +// more: +def matchEverything(obj: Any): String = obj match { + // You can match values: + case "Hello world" => "Got the string Hello world" + + // You can match by type: + case x: Double => "Got a Double: " + x + + // You can specify conditions: + case x: Int if x > 10000 => "Got a pretty big number!" + + // You can match case classes as before: + case Person(name, number) => s"Got contact info for $name!" + + // You can match regular expressions: + case email(name, domain) => s"Got email address $name@$domain" + + // You can match tuples: + case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c" + + // You can match data structures: + case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c" + + // You can nest patterns: + case List(List((1, 2, "YAY"))) => "Got a list of list of tuple" + + // Match any case (default) if all previous haven't matched + case _ => "Got unknown object" +} + +// In fact, you can pattern match any object with an "unapply" method. This +// feature is so powerful that Scala lets you define whole functions as +// patterns: +val patternFunc: Person => String = { + case Person("George", number) => s"George's number: $number" + case Person(name, number) => s"Random person's number: $number" +} + + +///////////////////////////////////////////////// +// 7. Functional Programming +///////////////////////////////////////////////// + +// Scala allows methods and functions to return, or take as parameters, other +// functions or methods. + +val add10: Int => Int = _ + 10 // A function taking an Int and returning an Int +List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element + +// Anonymous functions can be used instead of named functions: +List(1, 2, 3) map (x => x + 10) + +// And the underscore symbol, can be used if there is just one argument to the +// anonymous function. It gets bound as the variable +List(1, 2, 3) map (_ + 10) + +// If the anonymous block AND the function you are applying both take one +// argument, you can even omit the underscore +List("Dom", "Bob", "Natalia") foreach println + + +// Combinators +// Using `s` from above: +// val s = Set(1, 3, 7) + +s.map(sq) + +val sSquared = s. map(sq) + +sSquared.filter(_ < 10) + +sSquared.reduce (_+_) + +// The filter function takes a predicate (a function from A -> Boolean) and +// selects all elements which satisfy the predicate +List(1, 2, 3) filter (_ > 2) // List(3) +case class Person(name: String, age: Int) +List( + Person(name = "Dom", age = 23), + Person(name = "Bob", age = 30) +).filter(_.age > 25) // List(Person("Bob", 30)) + + +// Certain collections (such as List) in Scala have a `foreach` method, +// which takes as an argument a type returning Unit - that is, a void method +val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100) +aListOfNumbers foreach (x => println(x)) +aListOfNumbers foreach println + +// For comprehensions + +for { n <- s } yield sq(n) + +val nSquared2 = for { n <- s } yield sq(n) + +for { n <- nSquared2 if n < 10 } yield n + +for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared + +/* NB Those were not for loops. The semantics of a for loop is 'repeat', whereas + a for-comprehension defines a relationship between two sets of data. */ + + +///////////////////////////////////////////////// +// 8. Implicits +///////////////////////////////////////////////// + +/* WARNING WARNING: Implicits are a set of powerful features of Scala, and + * therefore it is easy to abuse them. Beginners to Scala should resist the + * temptation to use them until they understand not only how they work, but also + * best practices around them. We only include this section in the tutorial + * because they are so commonplace in Scala libraries that it is impossible to + * do anything meaningful without using a library that has implicits. This is + * meant for you to understand and work with implicits, not declare your own. + */ + +// Any value (vals, functions, objects, etc) can be declared to be implicit by +// using the, you guessed it, "implicit" keyword. Note we are using the Dog +// class from section 5 in these examples. +implicit val myImplicitInt = 100 +implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed) + +// By itself, implicit keyword doesn't change the behavior of the value, so +// above values can be used as usual. +myImplicitInt + 2 // => 102 +myImplicitFunction("Pitbull").breed // => "Golden Pitbull" + +// The difference is that these values are now eligible to be used when another +// piece of code "needs" an implicit value. One such situation is implicit +// function arguments: +def sendGreetings(toWhom: String)(implicit howMany: Int) = + s"Hello $toWhom, $howMany blessings to you and yours!" + +// If we supply a value for "howMany", the function behaves as usual +sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!" + +// But if we omit the implicit parameter, an implicit value of the same type is +// used, in this case, "myImplicitInt": +sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!" + +// Implicit function parameters enable us to simulate type classes in other +// functional languages. It is so often used that it gets its own shorthand. The +// following two lines mean the same thing: +// def foo[T](implicit c: C[T]) = ... +// def foo[T : C] = ... + + +// Another situation in which the compiler looks for an implicit is if you have +// obj.method(...) +// but "obj" doesn't have "method" as a method. In this case, if there is an +// implicit conversion of type A => B, where A is the type of obj, and B has a +// method called "method", that conversion is applied. So having +// myImplicitFunction above in scope, we can say: +"Retriever".breed // => "Golden Retriever" +"Sheperd".bark // => "Woof, woof!" + +// Here the String is first converted to Dog using our function above, and then +// the appropriate method is called. This is an extremely powerful feature, but +// again, it is not to be used lightly. In fact, when you defined the implicit +// function above, your compiler should have given you a warning, that you +// shouldn't do this unless you really know what you're doing. + + +///////////////////////////////////////////////// +// 9. Misc +///////////////////////////////////////////////// + +// Importing things +import scala.collection.immutable.List + +// Import all "sub packages" +import scala.collection.immutable._ + +// Import multiple classes in one statement +import scala.collection.immutable.{List, Map} + +// Rename an import using '=>' +import scala.collection.immutable.{List => ImmutableList} + +// Import all classes, except some. The following excludes Map and Set: +import scala.collection.immutable.{Map => _, Set => _, _} + +// Java classes can also be imported. Scala syntax can be used +import java.swing.{JFrame, JWindow} + +// Your programs entry point is defined in a scala file using an object, with a +// single method, main: +object Application { + def main(args: Array[String]): Unit = { + // stuff goes here. + } +} + +// Files can contain multiple classes and objects. Compile with scalac + + + + +// Input and output + +// To read a file line by line +import scala.io.Source +for(line <- Source.fromFile("myfile.txt").getLines()) + println(line) + +// To write a file use Java's PrintWriter +val writer = new PrintWriter("myfile.txt") +writer.write("Writing line for line" + util.Properties.lineSeparator) +writer.write("Another line here" + util.Properties.lineSeparator) +writer.close() + +``` + +## Further resources + +* [Scala for the impatient](http://horstmann.com/scala/) +* [Twitter Scala school](http://twitter.github.io/scala_school/) +* [The scala documentation](http://docs.scala-lang.org/) +* [Try Scala in your browser](http://scalatutorials.com/tour/) +* Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user) -- cgit v1.2.3 From 8defb7f6fec176fd406fd24856e6270c40909872 Mon Sep 17 00:00:00 2001 From: Pablo Arranz Ropero Date: Sat, 1 Jun 2019 13:17:07 +0200 Subject: Traducido hasta funciones --- es-es/scala.html.markdown | 66 ++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 35 deletions(-) (limited to 'es-es') diff --git a/es-es/scala.html.markdown b/es-es/scala.html.markdown index 319d5f9d..54425ced 100644 --- a/es-es/scala.html.markdown +++ b/es-es/scala.html.markdown @@ -100,29 +100,27 @@ var y = 10 y = 20 // y es 20 /* - Scala is a statically typed language, yet note that in the above declarations, - we did not specify a type. This is due to a language feature called type - inference. In most cases, Scala compiler can guess what the type of a variable - is, so you don't have to type it every time. We can explicitly declare the - type of a variable like so: + Scala es un lenguaje tipado estáticamente, aunque se puede ver en las expresiones anteriores que no hemos especificado un tipo. + Esto es debido a una funcionalidad del lenguaje llamada inferencia. En la mayoría de los casos, el compilador de Scala puede adivinar cual es el tipo de una variable, así que no hace falta escribirlo siempre. + Podemos declarar explicitamente el tipo de una variable de la siguiente manera: */ val z: Int = 10 val a: Double = 1.0 -// Notice automatic conversion from Int to Double, result is 10.0, not 10 +// Observa la conversión automática de Int a Double, el resultado será 10.0, no 10 val b: Double = 10 -// Boolean values +// Valores Booleanos true false -// Boolean operations +// Operaciones Booleanas !true // false !false // true true == false // false 10 > 5 // true -// Math is as per usual +// Las operaciones matemáticas se realizan como siempre 1 + 1 // 2 2 - 1 // 1 5 * 3 // 15 @@ -132,56 +130,54 @@ true == false // false 6 / 4.0 // 1.5 -// Evaluating an expression in the REPL gives you the type and value of the result +// Evaluar una expresión en REPL te da el tipo y valor del resultado 1 + 7 -/* The above line results in: +/* La linea superior tienen como resultado: scala> 1 + 7 res29: Int = 8 - This means the result of evaluating 1 + 7 is an object of type Int with a - value of 8 + Esto quiere decir que el resultado de evaluar 1 + 7 es un objeto de tipo Int con valor 8 - Note that "res29" is a sequentially generated variable name to store the - results of the expressions you typed, your output may differ. + Observa que "res29" es un nombre de variable secuencialmente generado para almacenar los resultados de las expresiones escritas, la salida que observes puede diferir en este sentido. */ -"Scala strings are surrounded by double quotes" -'a' // A Scala Char -// 'Single quote strings don't exist' <= This causes an error +"Las cadenas en Scala están rodeadas por comillas dobles" +'a' // Un caracter en Scala +// 'Las cadenas con comillas simples no existen' <= Esto causa un error -// Strings have the usual Java methods defined on them +// Las cadenas tienen los los típicos metodos de Java definidos "hello world".length "hello world".substring(2, 6) "hello world".replace("C", "3") -// They also have some extra Scala methods. See also: scala.collection.immutable.StringOps +// También tienen algunos métodos extra de Scala. Ver: scala.collection.immutable.StringOps "hello world".take(5) "hello world".drop(5) -// String interpolation: notice the prefix "s" +// Interpolación de cadenas: Observa el prefijo "s" val n = 45 -s"We have $n apples" // => "We have 45 apples" +s"Tengo $n manzanas" // => "Tengo 45 manzanas" -// Expressions inside interpolated strings are also possible +// Es posible colocar expresiones dentro de cadenas interpoladas val a = Array(11, 9, 6) -s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old." -s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples." -s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4" +s"Mi segunda hija tiene ${a(0) - a(2)} años." // => "Mi segunda hija tiene 5 años." +s"Hemos doblado la cantidad de ${n / 2.0} manzanas." // => "Hemos doblado la cantidad de 22.5 manzanas." +s"Potencia de 2: ${math.pow(2, 2)}" // => "Potencia de 2: 4" -// Formatting with interpolated strings with the prefix "f" -f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25" -f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454" +// Podemos formatear cadenas interpoladas con el prefijo "f" +f"Potencia de 5: ${math.pow(5, 2)}%1.0f" // "Potencia de 5: 25" +f"Raiz cuadrada de 122: ${math.sqrt(122)}%1.4f" // "Raiz cuadrada de 122: 11.0454" -// Raw strings, ignoring special characters. -raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r." +// Las cadenas puras ignoran caracteres especiales. +raw"Nueva linea: \n. Retorno: \r." // => "Nueva linea: \n. Retorno: \r." -// Some characters need to be "escaped", e.g. a double quote inside a string: -"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown"" +// Algunos caracteres necesitn ser escapados, por ejemplo unas comillas dobles dentro de una cadena: +"Se quedaron fuera de \"Rose and Crown\"" // => "Se quedaron fuera de "Rose and Crown"" -// Triple double-quotes let strings span multiple rows and contain quotes +// Las triples comillas dobles dejan que las cadenas se expandan por multiples filas y contengan comillas dobles o simples val html = """

Press belo', Joe

@@ -189,7 +185,7 @@ val html = """ ///////////////////////////////////////////////// -// 2. Functions +// 2. Funciones ///////////////////////////////////////////////// // Functions are defined like so: -- cgit v1.2.3 From 373bc005abe40851c372ba1d0c5a2d3082a72a72 Mon Sep 17 00:00:00 2001 From: Pablo Arranz Ropero Date: Sat, 1 Jun 2019 16:29:10 +0200 Subject: some more translated+ --- es-es/scala.html.markdown | 69 +++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 35 deletions(-) (limited to 'es-es') diff --git a/es-es/scala.html.markdown b/es-es/scala.html.markdown index 54425ced..f314bc9e 100644 --- a/es-es/scala.html.markdown +++ b/es-es/scala.html.markdown @@ -188,62 +188,61 @@ val html = """ // 2. Funciones ///////////////////////////////////////////////// -// Functions are defined like so: +// Las funciones se definen de la siguiente manera: // -// def functionName(args...): ReturnType = { body... } +// def nombreFuncion(argumentos...): TipoRetorno = { cuerpo... } // -// If you come from more traditional languages, notice the omission of the -// return keyword. In Scala, the last expression in the function block is the -// return value. -def sumOfSquares(x: Int, y: Int): Int = { +// Si estás acostumbrado a lenguajes más tradicionales, observa la omisión de la palabra return. +// En Scala, la última expresión en el bloque de función es el valor de retorno. +def sumaDeCuadrados(x: Int, y: Int): Int = { val x2 = x * x val y2 = y * y x2 + y2 } -// The { } can be omitted if the function body is a single expression: -def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y +// Los { } pueden omitirse si el cuerpo de la función es una única expresión: +def sumaDeCuadradosCorta(x: Int, y: Int): Int = x * x + y * y -// Syntax for calling functions is familiar: -sumOfSquares(3, 4) // => 25 +// La sintaxis para llamar funciones es familiar: +sumaDeCuadrados(3, 4) // => 25 -// You can use parameters names to specify them in different order -def subtract(x: Int, y: Int): Int = x - y +// Puedes usar los nombres de los parámetros para llamarlos en orden diferente +def restar(x: Int, y: Int): Int = x - y -subtract(10, 3) // => 7 -subtract(y=10, x=3) // => -7 +restar(10, 3) // => 7 +restar(y=10, x=3) // => -7 -// In most cases (with recursive functions the most notable exception), function -// return type can be omitted, and the same type inference we saw with variables -// will work with function return values: -def sq(x: Int) = x * x // Compiler can guess return type is Int +// En la mayoría de los casos (siendo las funciones recursivas la excepción más notable), +// el tipo de retorno de la función puede ser omitido, y la misma inferencia de tipos que vimos con las variables +// funcionará con los valores de retorno de las funciones: +def sq(x: Int) = x * x // El compilador puede adivinar que el tipo de retorno es Int -// Functions can have default parameters: -def addWithDefault(x: Int, y: Int = 5) = x + y -addWithDefault(1, 2) // => 3 -addWithDefault(1) // => 6 +// Las funciones pueden tener parametros por defecto: +def sumarConDefecto(x: Int, y: Int = 5) = x + y +sumarConDefecto(1, 2) // => 3 +sumarConDefecto(1) // => 6 -// Anonymous functions look like this: +// Las funciones anónimas se escriben así: (x: Int) => x * x -// Unlike defs, even the input type of anonymous functions can be omitted if the -// context makes it clear. Notice the type "Int => Int" which means a function -// that takes Int and returns Int. +// Al contrario que los defs, incluso el tipo de entrada de las funciones anónimas puede ser omitido si +// el contexto lo deja claro. Observa el tipo "Int => Int" que significa que es una función +// que recibe Int y retorna Int. val sq: Int => Int = x => x * x -// Anonymous functions can be called as usual: +// Las funciones anónimas pueden ser llamadas como las demás: sq(10) // => 100 -// If each argument in your anonymous function is -// used only once, Scala gives you an even shorter way to define them. These -// anonymous functions turn out to be extremely common, as will be obvious in -// the data structure section. -val addOne: Int => Int = _ + 1 -val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3) +// Si cada argumento en tu función anónima es usado solo una vez, +// Scala te da una manera incluso más corta de definirlos. +// Estas funciones anónimas son extremadamente comunes, +// como será obvio en la sección de estructuras de datos. +val sumarUno: Int => Int = _ + 1 +val sumaRara: (Int, Int) => Int = (_ * 2 + _ * 3) -addOne(5) // => 6 -weirdSum(2, 4) // => 16 +sumarUno(5) // => 6 +sumaRara(2, 4) // => 16 // The return keyword exists in Scala, but it only returns from the inner-most -- cgit v1.2.3 From 2d0a124200a24e3b1c2ed6574a6d970fe96c5557 Mon Sep 17 00:00:00 2001 From: Pablo Arranz Ropero Date: Sun, 2 Jun 2019 12:39:53 +0200 Subject: some more tanslated --- es-es/scala.html.markdown | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'es-es') diff --git a/es-es/scala.html.markdown b/es-es/scala.html.markdown index f314bc9e..1d09add0 100644 --- a/es-es/scala.html.markdown +++ b/es-es/scala.html.markdown @@ -245,23 +245,22 @@ sumarUno(5) // => 6 sumaRara(2, 4) // => 16 -// The return keyword exists in Scala, but it only returns from the inner-most -// def that surrounds it. -// WARNING: Using return in Scala is error-prone and should be avoided. -// It has no effect on anonymous functions. For example: +// La palabra return existe en Scala, pero solo retorna desde la función más interna que la rodea. +// ADVERTENCIA: Usar return en Scala puede inducir a errores y debe ser evitado +// No tiene efecto en funciones anónimas. Por ejemplo: def foo(x: Int): Int = { - val anonFunc: Int => Int = { z => + val funcAnon: Int => Int = { z => if (z > 5) - return z // This line makes z the return value of foo! + return z // Esta línea hace que z sea el valor de retorno de foo! else - z + 2 // This line is the return value of anonFunc + z + 2 // Esta línea es el valor de retorno de funcAnon } - anonFunc(x) // This line is the return value of foo + anonFunc(x) // Esta línea es el valor de retorno de foo } ///////////////////////////////////////////////// -// 3. Flow Control +// 3. Control del flujo ///////////////////////////////////////////////// 1 to 5 -- cgit v1.2.3 From 1108cfb30557db533d904dc9bd88e2709c723b97 Mon Sep 17 00:00:00 2001 From: Pablo Arranz Ropero Date: Sun, 2 Jun 2019 15:04:03 +0200 Subject: some more tanslated --- es-es/scala.html.markdown | 56 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'es-es') diff --git a/es-es/scala.html.markdown b/es-es/scala.html.markdown index 1d09add0..6bbe3a7c 100644 --- a/es-es/scala.html.markdown +++ b/es-es/scala.html.markdown @@ -268,44 +268,44 @@ val r = 1 to 5 r.foreach(println) r foreach println -// NB: Scala is quite lenient when it comes to dots and brackets - study the -// rules separately. This helps write DSLs and APIs that read like English +// Nota: Scala es un lenguaje muy permisivo cuando se trata de puntos y parentesis - estudia las +// reglas separadamente. Esto ayuda a escribir DSLs y APIs que se lean en lenguaje natural. -// Why doesn't `println` need any parameters here? -// Stay tuned for first-class functions in the Functional Programming section below! +// Por qué `println` no necesita parámetros aquí? +// Presta atención a las funciones de primera clase en la sección de Programación Funcional más abajo! (5 to 1 by -1) foreach (println) -// A while loop +// Un bucle while var i = 0 while (i < 10) { println("i " + i); i += 1 } -while (i < 10) { println("i " + i); i += 1 } // Yes, again. What happened? Why? +while (i < 10) { println("i " + i); i += 1 } // Si, de nuevo. Qué ocurrió? Por qué? -i // Show the value of i. Note that while is a loop in the classical sense - - // it executes sequentially while changing the loop variable. while is very - // fast, but using the combinators and comprehensions above is easier - // to understand and parallelize +i // Muestra el valor de i. Observa que while es un loop en el sentido clásico - + // se ejecuta secuencialmente mientras cambia la variable del bucle. while es muy + // rápido, pero los combinadores y comprensiones anteriores son más sencillos + // de entender y paralelizar -// A do-while loop +// Un bucle do-while i = 0 do { - println("i is still less than 10") + println("i es aún menor que 10") i += 1 } while (i < 10) -// Recursion is the idiomatic way of repeating an action in Scala (as in most -// other functional languages). -// Recursive functions need an explicit return type, the compiler can't infer it. -// Here it's Unit, which is analagous to a `void` return type in Java -def showNumbersInRange(a: Int, b: Int): Unit = { +// La recursion es la manera idiomática de repetir una acción en Scala (como en la mayoría de +// lenguajes funcionales). +// Las funciones recursivas necesitan un tipo de retorno explicito, el compilador no puede inferirlo. +// En Scala tenemos Unit, que es análogo al tipo de retorno `void` en Java +def enseñaNumerosEnUnRango(a: Int, b: Int): Unit = { print(a) if (a < b) - showNumbersInRange(a + 1, b) + enseñaNumerosEnUnRango(a + 1, b) } -showNumbersInRange(1, 14) +enseñaNumerosEnUnRango(1, 14) -// Conditionals +// Condicionales val x = 10 @@ -319,33 +319,33 @@ val text = if (x == 10) "yeah" else "nope" ///////////////////////////////////////////////// -// 4. Data Structures +// 4. Estructuras de datos ///////////////////////////////////////////////// val a = Array(1, 2, 3, 5, 8, 13) a(0) // Int = 1 a(3) // Int = 5 -a(21) // Throws an exception +a(21) // Lanza una excepción val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo") m("fork") // java.lang.String = tenedor m("spoon") // java.lang.String = cuchara -m("bottle") // Throws an exception +m("bottle") // Lanza una excepción -val safeM = m.withDefaultValue("no lo se") -safeM("bottle") // java.lang.String = no lo se +val mapaSeguro = m.withDefaultValue("no lo se") +mapaSeguro("bottle") // java.lang.String = no lo se val s = Set(1, 3, 7) s(0) // Boolean = false s(1) // Boolean = true -/* Look up the documentation of map here - +/* Hecha un vistazo a la documentación de Map aquí - * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map - * and make sure you can read it + * y asegúrate de que puedes leerla */ -// Tuples +// Tuplas (1, 2) -- cgit v1.2.3 From 8041ab30c122131b0e6dc4c65b7e37fb3376741b Mon Sep 17 00:00:00 2001 From: Pablo Date: Mon, 3 Jun 2019 12:57:37 +0200 Subject: more --- es-es/scala.html.markdown | 748 ---------------------------------------------- 1 file changed, 748 deletions(-) delete mode 100644 es-es/scala.html.markdown (limited to 'es-es') diff --git a/es-es/scala.html.markdown b/es-es/scala.html.markdown deleted file mode 100644 index 6bbe3a7c..00000000 --- a/es-es/scala.html.markdown +++ /dev/null @@ -1,748 +0,0 @@ ---- -language: Scala -filename: learnscala-es.scala -contributors: - - ["George Petrov", "http://github.com/petrovg"] - - ["Dominic Bou-Samra", "http://dbousamra.github.com"] - - ["Geoff Liu", "http://geoffliu.me"] - - ["Ha-Duong Nguyen", "http://reference-error.org"] -translators: - - ["Pablo Arranz Ropero", "http://arranzropablo.com"] -lang: es-es ---- - -Scala - El lenguaje escalable - -```scala - -///////////////////////////////////////////////// -// 0. Básicos -///////////////////////////////////////////////// -/* - Configurar Scala: - - 1) Descarga Scala - http://www.scala-lang.org/downloads - 2) Unzip/untar a tu carpeta elegida y pon la subcarpeta bin en tu variable de entorno `PATH` -*/ - -/* - Prueba REPL - - Scala tiene una herramienta llamada REPL (Read-Eval-Print Loop, en español: Bucle de lectura-evaluación-impresión) que es analogo a interpretes de la linea de comandos en muchos otros lenguajes. - Puedes escribir cualquier expresión en Scala y el resultado será evaluado e impreso. - - REPL es una herramienta muy práctica para testear y verificar código. - Puedes usarla mientras lees este tutorial para explorar conceptos por tu cuenta. -*/ - -// Inicia Scala REPL ejecutando `scala` en tu terminal. Deberías ver: -$ scala -scala> - -// Por defecto cada expresión que escribes es guardada como un nuevo valor numerado: -scala> 2 + 2 -res0: Int = 4 - -// Los valores por defecto pueden ser reusados. Fíjate en el tipo del valor mostrado en el resultado... -scala> res0 + 2 -res1: Int = 6 - -// Scala es un lenguaje fuertemente tipado. Puedes usar REPL para comprobar el tipo sin evaluar una expresión. -scala> :type (true, 2.0) -(Boolean, Double) - -// Las sesiones REPL pueden ser guardadas -scala> :save /sites/repl-test.scala - -// Se pueden cargar archivos en REPL -scala> :load /sites/repl-test.scala -Loading /sites/repl-test.scala... -res2: Int = 4 -res3: Int = 6 - -// Puedes buscar en tu historial reciente -scala> :h? -1 2 + 2 -2 res0 + 2 -3 :save /sites/repl-test.scala -4 :load /sites/repl-test.scala -5 :h? - -// Ahora que sabes como jugar, aprendamos un poco de Scala... - -///////////////////////////////////////////////// -// 1. Básicos -///////////////////////////////////////////////// - -// Los comentarios de una linea comienzan con dos barras inclinadas - -/* - Los comentarios de varias lineas, como ya has visto arriba, se hacen de esta manera. -*/ - -// Así imprimimos forzando una nueva linea en la siguiente impresión -println("Hola mundo!") -println(10) -// Hola mundo! -// 10 - -// Así imprimimos sin forzar una nueva linea en la siguiente impresión -print("Hola mundo") -print(10) -// Hola mundo10 - -// Para declarar valores usamos var o val. -// Valores decalrados con val son inmutables, mientras que los declarados con var son mutables. -// La inmutabilidad es algo bueno. -val x = 10 // x es 10 -x = 20 // error: reassignment to val -var y = 10 -y = 20 // y es 20 - -/* - Scala es un lenguaje tipado estáticamente, aunque se puede ver en las expresiones anteriores que no hemos especificado un tipo. - Esto es debido a una funcionalidad del lenguaje llamada inferencia. En la mayoría de los casos, el compilador de Scala puede adivinar cual es el tipo de una variable, así que no hace falta escribirlo siempre. - Podemos declarar explicitamente el tipo de una variable de la siguiente manera: -*/ -val z: Int = 10 -val a: Double = 1.0 - -// Observa la conversión automática de Int a Double, el resultado será 10.0, no 10 -val b: Double = 10 - -// Valores Booleanos -true -false - -// Operaciones Booleanas -!true // false -!false // true -true == false // false -10 > 5 // true - -// Las operaciones matemáticas se realizan como siempre -1 + 1 // 2 -2 - 1 // 1 -5 * 3 // 15 -6 / 2 // 3 -6 / 4 // 1 -6.0 / 4 // 1.5 -6 / 4.0 // 1.5 - - -// Evaluar una expresión en REPL te da el tipo y valor del resultado - -1 + 7 - -/* La linea superior tienen como resultado: - - scala> 1 + 7 - res29: Int = 8 - - Esto quiere decir que el resultado de evaluar 1 + 7 es un objeto de tipo Int con valor 8 - - Observa que "res29" es un nombre de variable secuencialmente generado para almacenar los resultados de las expresiones escritas, la salida que observes puede diferir en este sentido. -*/ - -"Las cadenas en Scala están rodeadas por comillas dobles" -'a' // Un caracter en Scala -// 'Las cadenas con comillas simples no existen' <= Esto causa un error - -// Las cadenas tienen los los típicos metodos de Java definidos -"hello world".length -"hello world".substring(2, 6) -"hello world".replace("C", "3") - -// También tienen algunos métodos extra de Scala. Ver: scala.collection.immutable.StringOps -"hello world".take(5) -"hello world".drop(5) - -// Interpolación de cadenas: Observa el prefijo "s" -val n = 45 -s"Tengo $n manzanas" // => "Tengo 45 manzanas" - -// Es posible colocar expresiones dentro de cadenas interpoladas -val a = Array(11, 9, 6) -s"Mi segunda hija tiene ${a(0) - a(2)} años." // => "Mi segunda hija tiene 5 años." -s"Hemos doblado la cantidad de ${n / 2.0} manzanas." // => "Hemos doblado la cantidad de 22.5 manzanas." -s"Potencia de 2: ${math.pow(2, 2)}" // => "Potencia de 2: 4" - -// Podemos formatear cadenas interpoladas con el prefijo "f" -f"Potencia de 5: ${math.pow(5, 2)}%1.0f" // "Potencia de 5: 25" -f"Raiz cuadrada de 122: ${math.sqrt(122)}%1.4f" // "Raiz cuadrada de 122: 11.0454" - -// Las cadenas puras ignoran caracteres especiales. -raw"Nueva linea: \n. Retorno: \r." // => "Nueva linea: \n. Retorno: \r." - -// Algunos caracteres necesitn ser escapados, por ejemplo unas comillas dobles dentro de una cadena: -"Se quedaron fuera de \"Rose and Crown\"" // => "Se quedaron fuera de "Rose and Crown"" - -// Las triples comillas dobles dejan que las cadenas se expandan por multiples filas y contengan comillas dobles o simples -val html = """ -

Press belo', Joe

- - """ - - -///////////////////////////////////////////////// -// 2. Funciones -///////////////////////////////////////////////// - -// Las funciones se definen de la siguiente manera: -// -// def nombreFuncion(argumentos...): TipoRetorno = { cuerpo... } -// -// Si estás acostumbrado a lenguajes más tradicionales, observa la omisión de la palabra return. -// En Scala, la última expresión en el bloque de función es el valor de retorno. -def sumaDeCuadrados(x: Int, y: Int): Int = { - val x2 = x * x - val y2 = y * y - x2 + y2 -} - -// Los { } pueden omitirse si el cuerpo de la función es una única expresión: -def sumaDeCuadradosCorta(x: Int, y: Int): Int = x * x + y * y - -// La sintaxis para llamar funciones es familiar: -sumaDeCuadrados(3, 4) // => 25 - -// Puedes usar los nombres de los parámetros para llamarlos en orden diferente -def restar(x: Int, y: Int): Int = x - y - -restar(10, 3) // => 7 -restar(y=10, x=3) // => -7 - -// En la mayoría de los casos (siendo las funciones recursivas la excepción más notable), -// el tipo de retorno de la función puede ser omitido, y la misma inferencia de tipos que vimos con las variables -// funcionará con los valores de retorno de las funciones: -def sq(x: Int) = x * x // El compilador puede adivinar que el tipo de retorno es Int - -// Las funciones pueden tener parametros por defecto: -def sumarConDefecto(x: Int, y: Int = 5) = x + y -sumarConDefecto(1, 2) // => 3 -sumarConDefecto(1) // => 6 - - -// Las funciones anónimas se escriben así: -(x: Int) => x * x - -// Al contrario que los defs, incluso el tipo de entrada de las funciones anónimas puede ser omitido si -// el contexto lo deja claro. Observa el tipo "Int => Int" que significa que es una función -// que recibe Int y retorna Int. -val sq: Int => Int = x => x * x - -// Las funciones anónimas pueden ser llamadas como las demás: -sq(10) // => 100 - -// Si cada argumento en tu función anónima es usado solo una vez, -// Scala te da una manera incluso más corta de definirlos. -// Estas funciones anónimas son extremadamente comunes, -// como será obvio en la sección de estructuras de datos. -val sumarUno: Int => Int = _ + 1 -val sumaRara: (Int, Int) => Int = (_ * 2 + _ * 3) - -sumarUno(5) // => 6 -sumaRara(2, 4) // => 16 - - -// La palabra return existe en Scala, pero solo retorna desde la función más interna que la rodea. -// ADVERTENCIA: Usar return en Scala puede inducir a errores y debe ser evitado -// No tiene efecto en funciones anónimas. Por ejemplo: -def foo(x: Int): Int = { - val funcAnon: Int => Int = { z => - if (z > 5) - return z // Esta línea hace que z sea el valor de retorno de foo! - else - z + 2 // Esta línea es el valor de retorno de funcAnon - } - anonFunc(x) // Esta línea es el valor de retorno de foo -} - - -///////////////////////////////////////////////// -// 3. Control del flujo -///////////////////////////////////////////////// - -1 to 5 -val r = 1 to 5 -r.foreach(println) - -r foreach println -// Nota: Scala es un lenguaje muy permisivo cuando se trata de puntos y parentesis - estudia las -// reglas separadamente. Esto ayuda a escribir DSLs y APIs que se lean en lenguaje natural. - -// Por qué `println` no necesita parámetros aquí? -// Presta atención a las funciones de primera clase en la sección de Programación Funcional más abajo! -(5 to 1 by -1) foreach (println) - -// Un bucle while -var i = 0 -while (i < 10) { println("i " + i); i += 1 } - -while (i < 10) { println("i " + i); i += 1 } // Si, de nuevo. Qué ocurrió? Por qué? - -i // Muestra el valor de i. Observa que while es un loop en el sentido clásico - - // se ejecuta secuencialmente mientras cambia la variable del bucle. while es muy - // rápido, pero los combinadores y comprensiones anteriores son más sencillos - // de entender y paralelizar - -// Un bucle do-while -i = 0 -do { - println("i es aún menor que 10") - i += 1 -} while (i < 10) - -// La recursion es la manera idiomática de repetir una acción en Scala (como en la mayoría de -// lenguajes funcionales). -// Las funciones recursivas necesitan un tipo de retorno explicito, el compilador no puede inferirlo. -// En Scala tenemos Unit, que es análogo al tipo de retorno `void` en Java -def enseñaNumerosEnUnRango(a: Int, b: Int): Unit = { - print(a) - if (a < b) - enseñaNumerosEnUnRango(a + 1, b) -} -enseñaNumerosEnUnRango(1, 14) - - -// Condicionales - -val x = 10 - -if (x == 1) println("yeah") -if (x == 10) println("yeah") -if (x == 11) println("yeah") -if (x == 11) println("yeah") else println("nay") - -println(if (x == 10) "yeah" else "nope") -val text = if (x == 10) "yeah" else "nope" - - -///////////////////////////////////////////////// -// 4. Estructuras de datos -///////////////////////////////////////////////// - -val a = Array(1, 2, 3, 5, 8, 13) -a(0) // Int = 1 -a(3) // Int = 5 -a(21) // Lanza una excepción - -val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo") -m("fork") // java.lang.String = tenedor -m("spoon") // java.lang.String = cuchara -m("bottle") // Lanza una excepción - -val mapaSeguro = m.withDefaultValue("no lo se") -mapaSeguro("bottle") // java.lang.String = no lo se - -val s = Set(1, 3, 7) -s(0) // Boolean = false -s(1) // Boolean = true - -/* Hecha un vistazo a la documentación de Map aquí - - * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map - * y asegúrate de que puedes leerla - */ - - -// Tuplas - -(1, 2) - -(4, 3, 2) - -(1, 2, "three") - -(a, 2, "three") - -// Why have this? -val divideInts = (x: Int, y: Int) => (x / y, x % y) - -// The function divideInts gives you the result and the remainder -divideInts(10, 3) // (Int, Int) = (3,1) - -// To access the elements of a tuple, use _._n where n is the 1-based index of -// the element -val d = divideInts(10, 3) // (Int, Int) = (3,1) - -d._1 // Int = 3 -d._2 // Int = 1 - -// Alternatively you can do multiple-variable assignment to tuple, which is more -// convenient and readable in many cases -val (div, mod) = divideInts(10, 3) - -div // Int = 3 -mod // Int = 1 - - -///////////////////////////////////////////////// -// 5. Object Oriented Programming -///////////////////////////////////////////////// - -/* - Aside: Everything we've done so far in this tutorial has been simple - expressions (values, functions, etc). These expressions are fine to type into - the command-line interpreter for quick tests, but they cannot exist by - themselves in a Scala file. For example, you cannot have just "val x = 5" in - a Scala file. Instead, the only top-level constructs allowed in Scala are: - - - objects - - classes - - case classes - - traits - - And now we will explain what these are. -*/ - -// classes are similar to classes in other languages. Constructor arguments are -// declared after the class name, and initialization is done in the class body. -class Dog(br: String) { - // Constructor code here - var breed: String = br - - // Define a method called bark, returning a String - def bark = "Woof, woof!" - - // Values and methods are assumed public. "protected" and "private" keywords - // are also available. - private def sleep(hours: Int) = - println(s"I'm sleeping for $hours hours") - - // Abstract methods are simply methods with no body. If we uncomment the - // def line below, class Dog would need to be declared abstract like so: - // abstract class Dog(...) { ... } - // def chaseAfter(what: String): String -} - -val mydog = new Dog("greyhound") -println(mydog.breed) // => "greyhound" -println(mydog.bark) // => "Woof, woof!" - - -// The "object" keyword creates a type AND a singleton instance of it. It is -// common for Scala classes to have a "companion object", where the per-instance -// behavior is captured in the classes themselves, but behavior related to all -// instance of that class go in objects. The difference is similar to class -// methods vs static methods in other languages. Note that objects and classes -// can have the same name. -object Dog { - def allKnownBreeds = List("pitbull", "shepherd", "retriever") - def createDog(breed: String) = new Dog(breed) -} - - -// Case classes are classes that have extra functionality built in. A common -// question for Scala beginners is when to use classes and when to use case -// classes. The line is quite fuzzy, but in general, classes tend to focus on -// encapsulation, polymorphism, and behavior. The values in these classes tend -// to be private, and only methods are exposed. The primary purpose of case -// classes is to hold immutable data. They often have few methods, and the -// methods rarely have side-effects. -case class Person(name: String, phoneNumber: String) - -// Create a new instance. Note cases classes don't need "new" -val george = Person("George", "1234") -val kate = Person("Kate", "4567") - -// With case classes, you get a few perks for free, like getters: -george.phoneNumber // => "1234" - -// Per field equality (no need to override .equals) -Person("George", "1234") == Person("Kate", "1236") // => false - -// Easy way to copy -// otherGeorge == Person("George", "9876") -val otherGeorge = george.copy(phoneNumber = "9876") - -// And many others. Case classes also get pattern matching for free, see below. - -// Traits -// Similar to Java interfaces, traits define an object type and method -// signatures. Scala allows partial implementation of those methods. -// Constructor parameters are not allowed. Traits can inherit from other -// traits or classes without parameters. - -trait Dog { - def breed: String - def color: String - def bark: Boolean = true - def bite: Boolean -} -class SaintBernard extends Dog { - val breed = "Saint Bernard" - val color = "brown" - def bite = false -} - -scala> b -res0: SaintBernard = SaintBernard@3e57cd70 -scala> b.breed -res1: String = Saint Bernard -scala> b.bark -res2: Boolean = true -scala> b.bite -res3: Boolean = false - -// A trait can also be used as Mixin. The class "extends" the first trait, -// but the keyword "with" can add additional traits. - -trait Bark { - def bark: String = "Woof" -} -trait Dog { - def breed: String - def color: String -} -class SaintBernard extends Dog with Bark { - val breed = "Saint Bernard" - val color = "brown" -} - -scala> val b = new SaintBernard -b: SaintBernard = SaintBernard@7b69c6ba -scala> b.bark -res0: String = Woof - - -///////////////////////////////////////////////// -// 6. Pattern Matching -///////////////////////////////////////////////// - -// Pattern matching is a powerful and commonly used feature in Scala. Here's how -// you pattern match a case class. NB: Unlike other languages, Scala cases do -// not need breaks, fall-through does not happen. - -def matchPerson(person: Person): String = person match { - // Then you specify the patterns: - case Person("George", number) => "We found George! His number is " + number - case Person("Kate", number) => "We found Kate! Her number is " + number - case Person(name, number) => "We matched someone : " + name + ", phone : " + number -} - -// Regular expressions are also built in. -// Create a regex with the `r` method on a string: -val email = "(.*)@(.*)".r - -// Pattern matching might look familiar to the switch statements in the C family -// of languages, but this is much more powerful. In Scala, you can match much -// more: -def matchEverything(obj: Any): String = obj match { - // You can match values: - case "Hello world" => "Got the string Hello world" - - // You can match by type: - case x: Double => "Got a Double: " + x - - // You can specify conditions: - case x: Int if x > 10000 => "Got a pretty big number!" - - // You can match case classes as before: - case Person(name, number) => s"Got contact info for $name!" - - // You can match regular expressions: - case email(name, domain) => s"Got email address $name@$domain" - - // You can match tuples: - case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c" - - // You can match data structures: - case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c" - - // You can nest patterns: - case List(List((1, 2, "YAY"))) => "Got a list of list of tuple" - - // Match any case (default) if all previous haven't matched - case _ => "Got unknown object" -} - -// In fact, you can pattern match any object with an "unapply" method. This -// feature is so powerful that Scala lets you define whole functions as -// patterns: -val patternFunc: Person => String = { - case Person("George", number) => s"George's number: $number" - case Person(name, number) => s"Random person's number: $number" -} - - -///////////////////////////////////////////////// -// 7. Functional Programming -///////////////////////////////////////////////// - -// Scala allows methods and functions to return, or take as parameters, other -// functions or methods. - -val add10: Int => Int = _ + 10 // A function taking an Int and returning an Int -List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element - -// Anonymous functions can be used instead of named functions: -List(1, 2, 3) map (x => x + 10) - -// And the underscore symbol, can be used if there is just one argument to the -// anonymous function. It gets bound as the variable -List(1, 2, 3) map (_ + 10) - -// If the anonymous block AND the function you are applying both take one -// argument, you can even omit the underscore -List("Dom", "Bob", "Natalia") foreach println - - -// Combinators -// Using `s` from above: -// val s = Set(1, 3, 7) - -s.map(sq) - -val sSquared = s. map(sq) - -sSquared.filter(_ < 10) - -sSquared.reduce (_+_) - -// The filter function takes a predicate (a function from A -> Boolean) and -// selects all elements which satisfy the predicate -List(1, 2, 3) filter (_ > 2) // List(3) -case class Person(name: String, age: Int) -List( - Person(name = "Dom", age = 23), - Person(name = "Bob", age = 30) -).filter(_.age > 25) // List(Person("Bob", 30)) - - -// Certain collections (such as List) in Scala have a `foreach` method, -// which takes as an argument a type returning Unit - that is, a void method -val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100) -aListOfNumbers foreach (x => println(x)) -aListOfNumbers foreach println - -// For comprehensions - -for { n <- s } yield sq(n) - -val nSquared2 = for { n <- s } yield sq(n) - -for { n <- nSquared2 if n < 10 } yield n - -for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared - -/* NB Those were not for loops. The semantics of a for loop is 'repeat', whereas - a for-comprehension defines a relationship between two sets of data. */ - - -///////////////////////////////////////////////// -// 8. Implicits -///////////////////////////////////////////////// - -/* WARNING WARNING: Implicits are a set of powerful features of Scala, and - * therefore it is easy to abuse them. Beginners to Scala should resist the - * temptation to use them until they understand not only how they work, but also - * best practices around them. We only include this section in the tutorial - * because they are so commonplace in Scala libraries that it is impossible to - * do anything meaningful without using a library that has implicits. This is - * meant for you to understand and work with implicits, not declare your own. - */ - -// Any value (vals, functions, objects, etc) can be declared to be implicit by -// using the, you guessed it, "implicit" keyword. Note we are using the Dog -// class from section 5 in these examples. -implicit val myImplicitInt = 100 -implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed) - -// By itself, implicit keyword doesn't change the behavior of the value, so -// above values can be used as usual. -myImplicitInt + 2 // => 102 -myImplicitFunction("Pitbull").breed // => "Golden Pitbull" - -// The difference is that these values are now eligible to be used when another -// piece of code "needs" an implicit value. One such situation is implicit -// function arguments: -def sendGreetings(toWhom: String)(implicit howMany: Int) = - s"Hello $toWhom, $howMany blessings to you and yours!" - -// If we supply a value for "howMany", the function behaves as usual -sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!" - -// But if we omit the implicit parameter, an implicit value of the same type is -// used, in this case, "myImplicitInt": -sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!" - -// Implicit function parameters enable us to simulate type classes in other -// functional languages. It is so often used that it gets its own shorthand. The -// following two lines mean the same thing: -// def foo[T](implicit c: C[T]) = ... -// def foo[T : C] = ... - - -// Another situation in which the compiler looks for an implicit is if you have -// obj.method(...) -// but "obj" doesn't have "method" as a method. In this case, if there is an -// implicit conversion of type A => B, where A is the type of obj, and B has a -// method called "method", that conversion is applied. So having -// myImplicitFunction above in scope, we can say: -"Retriever".breed // => "Golden Retriever" -"Sheperd".bark // => "Woof, woof!" - -// Here the String is first converted to Dog using our function above, and then -// the appropriate method is called. This is an extremely powerful feature, but -// again, it is not to be used lightly. In fact, when you defined the implicit -// function above, your compiler should have given you a warning, that you -// shouldn't do this unless you really know what you're doing. - - -///////////////////////////////////////////////// -// 9. Misc -///////////////////////////////////////////////// - -// Importing things -import scala.collection.immutable.List - -// Import all "sub packages" -import scala.collection.immutable._ - -// Import multiple classes in one statement -import scala.collection.immutable.{List, Map} - -// Rename an import using '=>' -import scala.collection.immutable.{List => ImmutableList} - -// Import all classes, except some. The following excludes Map and Set: -import scala.collection.immutable.{Map => _, Set => _, _} - -// Java classes can also be imported. Scala syntax can be used -import java.swing.{JFrame, JWindow} - -// Your programs entry point is defined in a scala file using an object, with a -// single method, main: -object Application { - def main(args: Array[String]): Unit = { - // stuff goes here. - } -} - -// Files can contain multiple classes and objects. Compile with scalac - - - - -// Input and output - -// To read a file line by line -import scala.io.Source -for(line <- Source.fromFile("myfile.txt").getLines()) - println(line) - -// To write a file use Java's PrintWriter -val writer = new PrintWriter("myfile.txt") -writer.write("Writing line for line" + util.Properties.lineSeparator) -writer.write("Another line here" + util.Properties.lineSeparator) -writer.close() - -``` - -## Further resources - -* [Scala for the impatient](http://horstmann.com/scala/) -* [Twitter Scala school](http://twitter.github.io/scala_school/) -* [The scala documentation](http://docs.scala-lang.org/) -* [Try Scala in your browser](http://scalatutorials.com/tour/) -* Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user) -- cgit v1.2.3 From 3b7b38ec349d1a231e3075bb8d823b704c8be893 Mon Sep 17 00:00:00 2001 From: Pablo Date: Wed, 5 Jun 2019 16:16:42 +0200 Subject: more --- es-es/scala-es.html.markdown | 749 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 749 insertions(+) create mode 100644 es-es/scala-es.html.markdown (limited to 'es-es') diff --git a/es-es/scala-es.html.markdown b/es-es/scala-es.html.markdown new file mode 100644 index 00000000..145c1d74 --- /dev/null +++ b/es-es/scala-es.html.markdown @@ -0,0 +1,749 @@ +--- +language: Scala +filename: learnscala-es.scala +contributors: + - ["George Petrov", "http://github.com/petrovg"] + - ["Dominic Bou-Samra", "http://dbousamra.github.com"] + - ["Geoff Liu", "http://geoffliu.me"] + - ["Ha-Duong Nguyen", "http://reference-error.org"] +translators: + - ["Pablo Arranz Ropero", "http://arranzropablo.com"] +lang: es-es +--- + +Scala - El lenguaje escalable + +```scala + +///////////////////////////////////////////////// +// 0. Básicos +///////////////////////////////////////////////// +/* + Configurar Scala: + + 1) Descarga Scala - http://www.scala-lang.org/downloads + 2) Unzip/untar a tu carpeta elegida y pon la subcarpeta bin en tu variable de entorno `PATH` +*/ + +/* + Prueba REPL + + Scala tiene una herramienta llamada REPL (Read-Eval-Print Loop, en español: Bucle de lectura-evaluación-impresión) que es analogo a interpretes de la linea de comandos en muchos otros lenguajes. + Puedes escribir cualquier expresión en Scala y el resultado será evaluado e impreso. + + REPL es una herramienta muy práctica para testear y verificar código. + Puedes usarla mientras lees este tutorial para explorar conceptos por tu cuenta. +*/ + +// Inicia Scala REPL ejecutando `scala` en tu terminal. Deberías ver: +$ scala +scala> + +// Por defecto cada expresión que escribes es guardada como un nuevo valor numerado: +scala> 2 + 2 +res0: Int = 4 + +// Los valores por defecto pueden ser reusados. Fíjate en el tipo del valor mostrado en el resultado... +scala> res0 + 2 +res1: Int = 6 + +// Scala es un lenguaje fuertemente tipado. Puedes usar REPL para comprobar el tipo sin evaluar una expresión. +scala> :type (true, 2.0) +(Boolean, Double) + +// Las sesiones REPL pueden ser guardadas +scala> :save /sites/repl-test.scala + +// Se pueden cargar archivos en REPL +scala> :load /sites/repl-test.scala +Loading /sites/repl-test.scala... +res2: Int = 4 +res3: Int = 6 + +// Puedes buscar en tu historial reciente +scala> :h? +1 2 + 2 +2 res0 + 2 +3 :save /sites/repl-test.scala +4 :load /sites/repl-test.scala +5 :h? + +// Ahora que sabes como jugar, aprendamos un poco de Scala... + +///////////////////////////////////////////////// +// 1. Básicos +///////////////////////////////////////////////// + +// Los comentarios de una linea comienzan con dos barras inclinadas + +/* + Los comentarios de varias lineas, como ya has visto arriba, se hacen de esta manera. +*/ + +// Así imprimimos forzando una nueva linea en la siguiente impresión +println("Hola mundo!") +println(10) +// Hola mundo! +// 10 + +// Así imprimimos sin forzar una nueva linea en la siguiente impresión +print("Hola mundo") +print(10) +// Hola mundo10 + +// Para declarar valores usamos var o val. +// Valores decalrados con val son inmutables, mientras que los declarados con var son mutables. +// La inmutabilidad es algo bueno. +val x = 10 // x es 10 +x = 20 // error: reassignment to val +var y = 10 +y = 20 // y es 20 + +/* + Scala es un lenguaje tipado estáticamente, aunque se puede ver en las expresiones anteriores que no hemos especificado un tipo. + Esto es debido a una funcionalidad del lenguaje llamada inferencia. En la mayoría de los casos, el compilador de Scala puede adivinar cual es el tipo de una variable, así que no hace falta escribirlo siempre. + Podemos declarar explicitamente el tipo de una variable de la siguiente manera: +*/ +val z: Int = 10 +val a: Double = 1.0 + +// Observa la conversión automática de Int a Double, el resultado será 10.0, no 10 +val b: Double = 10 + +// Valores Booleanos +true +false + +// Operaciones Booleanas +!true // false +!false // true +true == false // false +10 > 5 // true + +// Las operaciones matemáticas se realizan como siempre +1 + 1 // 2 +2 - 1 // 1 +5 * 3 // 15 +6 / 2 // 3 +6 / 4 // 1 +6.0 / 4 // 1.5 +6 / 4.0 // 1.5 + + +// Evaluar una expresión en REPL te da el tipo y valor del resultado + +1 + 7 + +/* La linea superior tienen como resultado: + + scala> 1 + 7 + res29: Int = 8 + + Esto quiere decir que el resultado de evaluar 1 + 7 es un objeto de tipo Int con valor 8 + + Observa que "res29" es un nombre de variable secuencialmente generado para almacenar los resultados de las expresiones escritas, la salida que observes puede diferir en este sentido. +*/ + +"Las cadenas en Scala están rodeadas por comillas dobles" +'a' // Un caracter en Scala +// 'Las cadenas con comillas simples no existen' <= Esto causa un error + +// Las cadenas tienen los los típicos metodos de Java definidos +"hello world".length +"hello world".substring(2, 6) +"hello world".replace("C", "3") + +// También tienen algunos métodos extra de Scala. Ver: scala.collection.immutable.StringOps +"hello world".take(5) +"hello world".drop(5) + +// Interpolación de cadenas: Observa el prefijo "s" +val n = 45 +s"Tengo $n manzanas" // => "Tengo 45 manzanas" + +// Es posible colocar expresiones dentro de cadenas interpoladas +val a = Array(11, 9, 6) +s"Mi segunda hija tiene ${a(0) - a(2)} años." // => "Mi segunda hija tiene 5 años." +s"Hemos doblado la cantidad de ${n / 2.0} manzanas." // => "Hemos doblado la cantidad de 22.5 manzanas." +s"Potencia de 2: ${math.pow(2, 2)}" // => "Potencia de 2: 4" + +// Podemos formatear cadenas interpoladas con el prefijo "f" +f"Potencia de 5: ${math.pow(5, 2)}%1.0f" // "Potencia de 5: 25" +f"Raiz cuadrada de 122: ${math.sqrt(122)}%1.4f" // "Raiz cuadrada de 122: 11.0454" + +// Las cadenas puras ignoran caracteres especiales. +raw"Nueva linea: \n. Retorno: \r." // => "Nueva linea: \n. Retorno: \r." + +// Algunos caracteres necesitn ser escapados, por ejemplo unas comillas dobles dentro de una cadena: +"Se quedaron fuera de \"Rose and Crown\"" // => "Se quedaron fuera de "Rose and Crown"" + +// Las triples comillas dobles dejan que las cadenas se expandan por multiples filas y contengan comillas dobles o simples +val html = """
+

Press belo', Joe

+ +
""" + + +///////////////////////////////////////////////// +// 2. Funciones +///////////////////////////////////////////////// + +// Las funciones se definen de la siguiente manera: +// +// def nombreFuncion(argumentos...): TipoRetorno = { cuerpo... } +// +// Si estás acostumbrado a lenguajes más tradicionales, observa la omisión de la palabra return. +// En Scala, la última expresión en el bloque de función es el valor de retorno. +def sumaDeCuadrados(x: Int, y: Int): Int = { + val x2 = x * x + val y2 = y * y + x2 + y2 +} + +// Los { } pueden omitirse si el cuerpo de la función es una única expresión: +def sumaDeCuadradosCorta(x: Int, y: Int): Int = x * x + y * y + +// La sintaxis para llamar funciones es familiar: +sumaDeCuadrados(3, 4) // => 25 + +// Puedes usar los nombres de los parámetros para llamarlos en orden diferente +def restar(x: Int, y: Int): Int = x - y + +restar(10, 3) // => 7 +restar(y=10, x=3) // => -7 + +// En la mayoría de los casos (siendo las funciones recursivas la excepción más notable), +// el tipo de retorno de la función puede ser omitido, y la misma inferencia de tipos que vimos con las variables +// funcionará con los valores de retorno de las funciones: +def sq(x: Int) = x * x // El compilador puede adivinar que el tipo de retorno es Int + +// Las funciones pueden tener parametros por defecto: +def sumarConDefecto(x: Int, y: Int = 5) = x + y +sumarConDefecto(1, 2) // => 3 +sumarConDefecto(1) // => 6 + + +// Las funciones anónimas se escriben así: +(x: Int) => x * x + +// Al contrario que los defs, incluso el tipo de entrada de las funciones anónimas puede ser omitido si +// el contexto lo deja claro. Observa el tipo "Int => Int" que significa que es una función +// que recibe Int y retorna Int. +val sq: Int => Int = x => x * x + +// Las funciones anónimas pueden ser llamadas como las demás: +sq(10) // => 100 + +// Si cada argumento en tu función anónima es usado solo una vez, +// Scala te da una manera incluso más corta de definirlos. +// Estas funciones anónimas son extremadamente comunes, +// como será obvio en la sección de estructuras de datos. +val sumarUno: Int => Int = _ + 1 +val sumaRara: (Int, Int) => Int = (_ * 2 + _ * 3) + +sumarUno(5) // => 6 +sumaRara(2, 4) // => 16 + + +// La palabra return existe en Scala, pero solo retorna desde la función más interna que la rodea. +// ADVERTENCIA: Usar return en Scala puede inducir a errores y debe ser evitado +// No tiene efecto en funciones anónimas. Por ejemplo: +def foo(x: Int): Int = { + val funcAnon: Int => Int = { z => + if (z > 5) + return z // Esta línea hace que z sea el valor de retorno de foo! + else + z + 2 // Esta línea es el valor de retorno de funcAnon + } + anonFunc(x) // Esta línea es el valor de retorno de foo +} + + +///////////////////////////////////////////////// +// 3. Control del flujo +///////////////////////////////////////////////// + +1 to 5 +val r = 1 to 5 +r.foreach(println) + +r foreach println +// Nota: Scala es un lenguaje muy permisivo cuando se trata de puntos y parentesis - estudia las +// reglas separadamente. Esto ayuda a escribir DSLs y APIs que se lean en lenguaje natural. + +// Por qué `println` no necesita parámetros aquí? +// Presta atención a las funciones de primera clase en la sección de Programación Funcional más abajo! +(5 to 1 by -1) foreach (println) + +// Un bucle while +var i = 0 +while (i < 10) { println("i " + i); i += 1 } + +while (i < 10) { println("i " + i); i += 1 } // Si, de nuevo. Qué ocurrió? Por qué? + +i // Muestra el valor de i. Observa que while es un loop en el sentido clásico - + // se ejecuta secuencialmente mientras cambia la variable del bucle. while es muy + // rápido, pero los combinadores y comprensiones anteriores son más sencillos + // de entender y paralelizar + +// Un bucle do-while +i = 0 +do { + println("i es aún menor que 10") + i += 1 +} while (i < 10) + +// La recursion es la manera idiomática de repetir una acción en Scala (como en la mayoría de +// lenguajes funcionales). +// Las funciones recursivas necesitan un tipo de retorno explicito, el compilador no puede inferirlo. +// En Scala tenemos Unit, que es análogo al tipo de retorno `void` en Java +def enseñaNumerosEnUnRango(a: Int, b: Int): Unit = { + print(a) + if (a < b) + enseñaNumerosEnUnRango(a + 1, b) +} +enseñaNumerosEnUnRango(1, 14) + + +// Condicionales + +val x = 10 + +if (x == 1) println("yeah") +if (x == 10) println("yeah") +if (x == 11) println("yeah") +if (x == 11) println("yeah") else println("nay") + +println(if (x == 10) "yeah" else "nope") +val text = if (x == 10) "yeah" else "nope" + + +///////////////////////////////////////////////// +// 4. Estructuras de datos +///////////////////////////////////////////////// + +val a = Array(1, 2, 3, 5, 8, 13) +a(0) // Int = 1 +a(3) // Int = 5 +a(21) // Lanza una excepción + +val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo") +m("fork") // java.lang.String = tenedor +m("spoon") // java.lang.String = cuchara +m("bottle") // Lanza una excepción + +val mapaSeguro = m.withDefaultValue("no lo se") +mapaSeguro("bottle") // java.lang.String = no lo se + +val s = Set(1, 3, 7) +s(0) // Boolean = false +s(1) // Boolean = true + +/* Hecha un vistazo a la documentación de Map aquí - + * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map + * y asegúrate de que puedes leerla + */ + + +// Tuplas + +(1, 2) + +(4, 3, 2) + +(1, 2, "three") + +(a, 2, "three") + +// Por qué tener esto? +val dividirEnteros = (x: Int, y: Int) => (x / y, x % y) + +// La función dividirEnteros te da el resultado y el resto +dividirEnteros(10, 3) // (Int, Int) = (3,1) + +// Para acceder a los elementos de una tupla, usa _._n donde n es el indice (comenzando por 1) +// del elemento +val d = dividirEnteros(10, 3) // (Int, Int) = (3,1) + +d._1 // Int = 3 +d._2 // Int = 1 + +// Alternativamente puedes asignar multiples variables desde una tupla, lo que +// resulta más conveniente y legible en muchos casos. +val (div, mod) = dividirEnteros(10, 3) + +div // Int = 3 +mod // Int = 1 + + +///////////////////////////////////////////////// +// 5. Programación Orientada a Objetos +///////////////////////////////////////////////// + +/* + Nota: Todo lo que hemos hecho hasta ahora en este tutorial han sido + simples expresiones (valores, funciones, etc). Estas expresiones son validas + para hacer pruebas rapidas en el interprete de la linea de comandos, + pero no pueden existir por si solas en un archivo de Scala. Por ejemplo, + no puedes tener simplemente "val x = 5" en un archivo Scala. En lugar de eso, + las únicas construcciones de alto nivel en Scala son: + + - Objetos + - Clases + - Case clases + - Traits + + Y ahora explicaremos lo que son estas. +*/ + +// Las clases son similares a las clases de otros lenguajes. Los argumentos del constructor +// son declarados despues del nombre de la clase, y la inicialización se hace en el cuerpo de la clase. +class Perro(r: String) { + // Código del constructor aquí + var raza: String = r + + // Define un método llamado ladrar, que devuelva un String + def ladrar = "Woof, woof!" + + // Los valores y métodos son asumidos como públicos. + // Las palabras "protected" y "private" también son válidas. + private def dormir(horas: Int) = + println(s"Estoy durmiendo $horas horas") + + // Los métodos abstractos son simplemente métodos sin cuerpo. + // Si descomentamos la linea de debajo, la clase Perro necesitaría ser abstracta: + // abstract class Perro(...) { ... } + // def perseguir(algo: String): String +} + +val miperro = new Dog("greyhound") +println(mydog.raza) // => "greyhound" +println(mydog.ladrar) // => "Woof, woof!" + + +// La palabra "object" crea un tipo y una instancia singleton de ese tipo. +// Es común que las clases en Scala tengan un "companion object", de manera que +// el comportamiento por instancia es controlado por las clases y el comportamiento +// relacionado a todas las instancias de esa clase es controlado por el objeto +// La relación es similar a los métodos de las clases con los métodos estáticos +// en otros lenguajes. Observa que los objetos y clases pueden tener el mismo nombre. +object Perro { + def todasLasRazasConocidas = List("pitbull", "shepherd", "retriever") + def crearPerro(raza: String) = new Dog(breed) +} + + +// Case clases son clases que tienen funcionalidad extra añadida. Una pregunta +// común para los principiantes en Scala es cuando usar case clases y cuando usar +// clases. La linea no está bien definida, pero en general, las clases tienden a +// enfocarse en la encapsulación, polimorfismo y comportamiento. Los valores en +// estas clases tienden a ser privados, y solo se exponen los métodos. +// El propósito principal de las case clases es tener datos inmutables. +// A menudo tienen pocos métodos, y los métodos raramente tienen efectos secundarios. +case class Persona(nombre: String, telefono: String) + +// Create a new instance. Note cases classes don't need "new" +val george = Persona("George", "1234") +val kate = Persona("Kate", "4567") + +// With case classes, you get a few perks for free, like getters: +george.phoneNumber // => "1234" + +// Per field equality (no need to override .equals) +Person("George", "1234") == Person("Kate", "1236") // => false + +// Easy way to copy +// otherGeorge == Person("George", "9876") +val otherGeorge = george.copy(phoneNumber = "9876") + +// And many others. Case classes also get pattern matching for free, see below. + +// Traits +// Similar to Java interfaces, traits define an object type and method +// signatures. Scala allows partial implementation of those methods. +// Constructor parameters are not allowed. Traits can inherit from other +// traits or classes without parameters. + +trait Dog { + def breed: String + def color: String + def bark: Boolean = true + def bite: Boolean +} +class SaintBernard extends Dog { + val breed = "Saint Bernard" + val color = "brown" + def bite = false +} + +scala> b +res0: SaintBernard = SaintBernard@3e57cd70 +scala> b.breed +res1: String = Saint Bernard +scala> b.bark +res2: Boolean = true +scala> b.bite +res3: Boolean = false + +// A trait can also be used as Mixin. The class "extends" the first trait, +// but the keyword "with" can add additional traits. + +trait Bark { + def bark: String = "Woof" +} +trait Dog { + def breed: String + def color: String +} +class SaintBernard extends Dog with Bark { + val breed = "Saint Bernard" + val color = "brown" +} + +scala> val b = new SaintBernard +b: SaintBernard = SaintBernard@7b69c6ba +scala> b.bark +res0: String = Woof + + +///////////////////////////////////////////////// +// 6. Pattern Matching +///////////////////////////////////////////////// + +// Pattern matching is a powerful and commonly used feature in Scala. Here's how +// you pattern match a case class. NB: Unlike other languages, Scala cases do +// not need breaks, fall-through does not happen. + +def matchPerson(person: Person): String = person match { + // Then you specify the patterns: + case Person("George", number) => "We found George! His number is " + number + case Person("Kate", number) => "We found Kate! Her number is " + number + case Person(name, number) => "We matched someone : " + name + ", phone : " + number +} + +// Regular expressions are also built in. +// Create a regex with the `r` method on a string: +val email = "(.*)@(.*)".r + +// Pattern matching might look familiar to the switch statements in the C family +// of languages, but this is much more powerful. In Scala, you can match much +// more: +def matchEverything(obj: Any): String = obj match { + // You can match values: + case "Hello world" => "Got the string Hello world" + + // You can match by type: + case x: Double => "Got a Double: " + x + + // You can specify conditions: + case x: Int if x > 10000 => "Got a pretty big number!" + + // You can match case classes as before: + case Person(name, number) => s"Got contact info for $name!" + + // You can match regular expressions: + case email(name, domain) => s"Got email address $name@$domain" + + // You can match tuples: + case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c" + + // You can match data structures: + case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c" + + // You can nest patterns: + case List(List((1, 2, "YAY"))) => "Got a list of list of tuple" + + // Match any case (default) if all previous haven't matched + case _ => "Got unknown object" +} + +// In fact, you can pattern match any object with an "unapply" method. This +// feature is so powerful that Scala lets you define whole functions as +// patterns: +val patternFunc: Person => String = { + case Person("George", number) => s"George's number: $number" + case Person(name, number) => s"Random person's number: $number" +} + + +///////////////////////////////////////////////// +// 7. Functional Programming +///////////////////////////////////////////////// + +// Scala allows methods and functions to return, or take as parameters, other +// functions or methods. + +val add10: Int => Int = _ + 10 // A function taking an Int and returning an Int +List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element + +// Anonymous functions can be used instead of named functions: +List(1, 2, 3) map (x => x + 10) + +// And the underscore symbol, can be used if there is just one argument to the +// anonymous function. It gets bound as the variable +List(1, 2, 3) map (_ + 10) + +// If the anonymous block AND the function you are applying both take one +// argument, you can even omit the underscore +List("Dom", "Bob", "Natalia") foreach println + + +// Combinators +// Using `s` from above: +// val s = Set(1, 3, 7) + +s.map(sq) + +val sSquared = s. map(sq) + +sSquared.filter(_ < 10) + +sSquared.reduce (_+_) + +// The filter function takes a predicate (a function from A -> Boolean) and +// selects all elements which satisfy the predicate +List(1, 2, 3) filter (_ > 2) // List(3) +case class Person(name: String, age: Int) +List( + Person(name = "Dom", age = 23), + Person(name = "Bob", age = 30) +).filter(_.age > 25) // List(Person("Bob", 30)) + + +// Certain collections (such as List) in Scala have a `foreach` method, +// which takes as an argument a type returning Unit - that is, a void method +val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100) +aListOfNumbers foreach (x => println(x)) +aListOfNumbers foreach println + +// For comprehensions + +for { n <- s } yield sq(n) + +val nSquared2 = for { n <- s } yield sq(n) + +for { n <- nSquared2 if n < 10 } yield n + +for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared + +/* NB Those were not for loops. The semantics of a for loop is 'repeat', whereas + a for-comprehension defines a relationship between two sets of data. */ + + +///////////////////////////////////////////////// +// 8. Implicits +///////////////////////////////////////////////// + +/* WARNING WARNING: Implicits are a set of powerful features of Scala, and + * therefore it is easy to abuse them. Beginners to Scala should resist the + * temptation to use them until they understand not only how they work, but also + * best practices around them. We only include this section in the tutorial + * because they are so commonplace in Scala libraries that it is impossible to + * do anything meaningful without using a library that has implicits. This is + * meant for you to understand and work with implicits, not declare your own. + */ + +// Any value (vals, functions, objects, etc) can be declared to be implicit by +// using the, you guessed it, "implicit" keyword. Note we are using the Dog +// class from section 5 in these examples. +implicit val myImplicitInt = 100 +implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed) + +// By itself, implicit keyword doesn't change the behavior of the value, so +// above values can be used as usual. +myImplicitInt + 2 // => 102 +myImplicitFunction("Pitbull").breed // => "Golden Pitbull" + +// The difference is that these values are now eligible to be used when another +// piece of code "needs" an implicit value. One such situation is implicit +// function arguments: +def sendGreetings(toWhom: String)(implicit howMany: Int) = + s"Hello $toWhom, $howMany blessings to you and yours!" + +// If we supply a value for "howMany", the function behaves as usual +sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!" + +// But if we omit the implicit parameter, an implicit value of the same type is +// used, in this case, "myImplicitInt": +sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!" + +// Implicit function parameters enable us to simulate type classes in other +// functional languages. It is so often used that it gets its own shorthand. The +// following two lines mean the same thing: +// def foo[T](implicit c: C[T]) = ... +// def foo[T : C] = ... + + +// Another situation in which the compiler looks for an implicit is if you have +// obj.method(...) +// but "obj" doesn't have "method" as a method. In this case, if there is an +// implicit conversion of type A => B, where A is the type of obj, and B has a +// method called "method", that conversion is applied. So having +// myImplicitFunction above in scope, we can say: +"Retriever".breed // => "Golden Retriever" +"Sheperd".bark // => "Woof, woof!" + +// Here the String is first converted to Dog using our function above, and then +// the appropriate method is called. This is an extremely powerful feature, but +// again, it is not to be used lightly. In fact, when you defined the implicit +// function above, your compiler should have given you a warning, that you +// shouldn't do this unless you really know what you're doing. + + +///////////////////////////////////////////////// +// 9. Misc +///////////////////////////////////////////////// + +// Importing things +import scala.collection.immutable.List + +// Import all "sub packages" +import scala.collection.immutable._ + +// Import multiple classes in one statement +import scala.collection.immutable.{List, Map} + +// Rename an import using '=>' +import scala.collection.immutable.{List => ImmutableList} + +// Import all classes, except some. The following excludes Map and Set: +import scala.collection.immutable.{Map => _, Set => _, _} + +// Java classes can also be imported. Scala syntax can be used +import java.swing.{JFrame, JWindow} + +// Your programs entry point is defined in a scala file using an object, with a +// single method, main: +object Application { + def main(args: Array[String]): Unit = { + // stuff goes here. + } +} + +// Files can contain multiple classes and objects. Compile with scalac + + + + +// Input and output + +// To read a file line by line +import scala.io.Source +for(line <- Source.fromFile("myfile.txt").getLines()) + println(line) + +// To write a file use Java's PrintWriter +val writer = new PrintWriter("myfile.txt") +writer.write("Writing line for line" + util.Properties.lineSeparator) +writer.write("Another line here" + util.Properties.lineSeparator) +writer.close() + +``` + +## Further resources + +* [Scala for the impatient](http://horstmann.com/scala/) +* [Twitter Scala school](http://twitter.github.io/scala_school/) +* [The scala documentation](http://docs.scala-lang.org/) +* [Try Scala in your browser](http://scalatutorials.com/tour/) +* Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user) -- cgit v1.2.3 From a2c6510c23957d0069d666c424e9845c49465413 Mon Sep 17 00:00:00 2001 From: Pablo Date: Thu, 6 Jun 2019 16:14:06 +0200 Subject: more --- es-es/scala-es.html.markdown | 121 ++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 60 deletions(-) (limited to 'es-es') diff --git a/es-es/scala-es.html.markdown b/es-es/scala-es.html.markdown index 145c1d74..74a043a0 100644 --- a/es-es/scala-es.html.markdown +++ b/es-es/scala-es.html.markdown @@ -442,101 +442,102 @@ object Perro { // A menudo tienen pocos métodos, y los métodos raramente tienen efectos secundarios. case class Persona(nombre: String, telefono: String) -// Create a new instance. Note cases classes don't need "new" +// Para crear instancia nuevas, observa que las case clases no necesitan "new" val george = Persona("George", "1234") val kate = Persona("Kate", "4567") -// With case classes, you get a few perks for free, like getters: -george.phoneNumber // => "1234" +// Con las case clases tienes unas pocas ventajas, como el acceso a los campos: +george.telefono // => "1234" -// Per field equality (no need to override .equals) -Person("George", "1234") == Person("Kate", "1236") // => false +// Para la igualdad de campos no necesitas sobreescribir el método equals +Persona("George", "1234") == Persona("Kate", "1236") // => false -// Easy way to copy -// otherGeorge == Person("George", "9876") -val otherGeorge = george.copy(phoneNumber = "9876") +// Manera fácil de copiar +// otroGeorge == Persona("George", "9876") +val otroGeorge = george.copy(telefono = "9876") -// And many others. Case classes also get pattern matching for free, see below. +// Y muchas otras. Las case clases también tienen comparación de patrones, que veremos más abajo. // Traits -// Similar to Java interfaces, traits define an object type and method -// signatures. Scala allows partial implementation of those methods. -// Constructor parameters are not allowed. Traits can inherit from other -// traits or classes without parameters. +// De manera similar a las interfaces Java, los traits definen un tipo de objeto y métodos. +// Scala permite la implementación parcial de dichos métodos. +// No se permiten parámetros de constructor. Los traits pueden heredar de otros traits o +// clases sin parámetros. -trait Dog { - def breed: String +trait Perro { + def raza: String def color: String - def bark: Boolean = true - def bite: Boolean + def ladra: Boolean = true + def muerde: Boolean } -class SaintBernard extends Dog { - val breed = "Saint Bernard" - val color = "brown" - def bite = false +class SanBernardo extends Perro { + val raza = "San Bernardo" + val color = "marrón" + def muerde = false } scala> b -res0: SaintBernard = SaintBernard@3e57cd70 -scala> b.breed -res1: String = Saint Bernard -scala> b.bark +res0: SanBernardo = SanBernardo@3e57cd70 +scala> b.raza +res1: String = San Bernardo +scala> b.ladra res2: Boolean = true -scala> b.bite +scala> b.muerde res3: Boolean = false -// A trait can also be used as Mixin. The class "extends" the first trait, -// but the keyword "with" can add additional traits. +// Un trait tambien puede ser usado mezclado con otros traits. +// La clase extiende el primer trait, pero la palabra "with" +// puede añadir traits adicionales. -trait Bark { - def bark: String = "Woof" +trait Ladra { + def ladra: String = "Guau" } -trait Dog { - def breed: String +trait Perro { + def raza: String def color: String } -class SaintBernard extends Dog with Bark { - val breed = "Saint Bernard" - val color = "brown" +class SanBernardo extends Perro with Ladra { + val raza = "San Bernardo" + val color = "marrón" } -scala> val b = new SaintBernard -b: SaintBernard = SaintBernard@7b69c6ba -scala> b.bark -res0: String = Woof +scala> val b = new SanBernardo +b: SanBernardo = SanBernardo@7b69c6ba +scala> b.ladra +res0: String = Guau ///////////////////////////////////////////////// -// 6. Pattern Matching +// 6. Comparación de patrones ///////////////////////////////////////////////// -// Pattern matching is a powerful and commonly used feature in Scala. Here's how -// you pattern match a case class. NB: Unlike other languages, Scala cases do -// not need breaks, fall-through does not happen. +// La comparación de patrones es una poderosa función de Scala. +// Ahora veremos como comparar patrones en una case clase. +// Nota: A diferencia de otros lenguajes, Scala "cases" no necesitan +// "break", porque no ejecuta los "case" posteriores. -def matchPerson(person: Person): String = person match { - // Then you specify the patterns: - case Person("George", number) => "We found George! His number is " + number - case Person("Kate", number) => "We found Kate! Her number is " + number - case Person(name, number) => "We matched someone : " + name + ", phone : " + number +def comparaPersona(persona: Persona): String = persona match { + // Aqui especificas los patrones: + case Persona("George", telefono) => "Hemos encontrado a George! Su número es " + telefono + case Persona("Kate", telefono) => "Hemos encontrado a Kate! Su número es " + telefono + case Persona(nombre, telefono) => "Hemos encontrado alguien : " + nombre + ", teléfono : " + telefono } -// Regular expressions are also built in. -// Create a regex with the `r` method on a string: +// Las expresiones regulares también están incorporadas. +// Creas una expresión regular con el método `r` en una cadena: val email = "(.*)@(.*)".r -// Pattern matching might look familiar to the switch statements in the C family -// of languages, but this is much more powerful. In Scala, you can match much -// more: -def matchEverything(obj: Any): String = obj match { - // You can match values: - case "Hello world" => "Got the string Hello world" +// La comparación de patrones puede parecerse al bloque switch en la familia de lenguajes de C, +// pero aquí es mucho más poderosa. En Scala, puedes hacer más comparaciones: +def comparaTodo(obj: Any): String = obj match { + // Puedes comparar valores: + case "Hola mundo" => "Tengo la cadena Hola mundo" - // You can match by type: - case x: Double => "Got a Double: " + x + // Puedes comparar tipos: + case x: Double => "Tengo un double: " + x - // You can specify conditions: - case x: Int if x > 10000 => "Got a pretty big number!" + // Puedes especificar condiciones: + case x: Int if x > 10000 => "Tengo un número muy grande!" // You can match case classes as before: case Person(name, number) => s"Got contact info for $name!" -- cgit v1.2.3 From 94c184f499277e3e5e514f45dbfb0a5075233b58 Mon Sep 17 00:00:00 2001 From: Pablo Date: Fri, 7 Jun 2019 16:07:39 +0200 Subject: more translated --- es-es/scala-es.html.markdown | 157 +++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 81 deletions(-) (limited to 'es-es') diff --git a/es-es/scala-es.html.markdown b/es-es/scala-es.html.markdown index 74a043a0..355e74c5 100644 --- a/es-es/scala-es.html.markdown +++ b/es-es/scala-es.html.markdown @@ -539,138 +539,133 @@ def comparaTodo(obj: Any): String = obj match { // Puedes especificar condiciones: case x: Int if x > 10000 => "Tengo un número muy grande!" - // You can match case classes as before: - case Person(name, number) => s"Got contact info for $name!" + // Puedes comparar case clases como antes: + case Persona(nombre, telefono) => s"Tengo la información de contacto de $nombre!" - // You can match regular expressions: - case email(name, domain) => s"Got email address $name@$domain" + // Puedes comparar expresiones regulares: + case email(nombre, dominio) => s"Tengo la dirección de correo $nombre@$dominio" - // You can match tuples: - case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c" + // Puedes comparar tuplas: + case (a: Int, b: Double, c: String) => s"Tengo la tupla: $a, $b, $c" - // You can match data structures: - case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c" + // Puedes comparar estructuras: + case List(1, b, c) => s"Tengo un alista con tres elementos que empieza con 1: 1, $b, $c" - // You can nest patterns: - case List(List((1, 2, "YAY"))) => "Got a list of list of tuple" + // Puedes anidar patrones: + case List(List((1, 2, "YAY"))) => "Tengo una lista de listas de tuplas" - // Match any case (default) if all previous haven't matched - case _ => "Got unknown object" + // Comparar cualquier case (default) si todos los anteriores no han coincido + case _ => "Tengo un objeto desconocido" } -// In fact, you can pattern match any object with an "unapply" method. This -// feature is so powerful that Scala lets you define whole functions as -// patterns: -val patternFunc: Person => String = { - case Person("George", number) => s"George's number: $number" - case Person(name, number) => s"Random person's number: $number" +// De hecho puedes comparar un patrón con cualquier objeto con el método "unapply". +// Esta función es tan poderosa que Scala te deja definir funciones enteras como patrones: +val funcPatron: Person => String = { + case Persona("George", telefono) => s"Teléfono de George: $telefono" + case Persona(nombre, telefono) => s"Teléfono de una persona aleatoria: $telefono" } ///////////////////////////////////////////////// -// 7. Functional Programming +// 7. Programación funcional ///////////////////////////////////////////////// -// Scala allows methods and functions to return, or take as parameters, other -// functions or methods. +// Scala permite a los métodos y funciones devolver o +// recibir como parámetros otras funciones o métodos -val add10: Int => Int = _ + 10 // A function taking an Int and returning an Int -List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element +val suma10: Int => Int = _ + 10 // Una función que recibe y devuelve un Int +List(1, 2, 3) map suma10 // List(11, 12, 13) - suma10 es aplicado a cada elemento -// Anonymous functions can be used instead of named functions: +// Las funciones anónimas pueden ser usadas en vez de funciones con nombre: List(1, 2, 3) map (x => x + 10) -// And the underscore symbol, can be used if there is just one argument to the -// anonymous function. It gets bound as the variable +// Y la barra baja puede ser usada si solo hay un argumento en la función anónima. +// Se usa como la variable. List(1, 2, 3) map (_ + 10) -// If the anonymous block AND the function you are applying both take one -// argument, you can even omit the underscore +// Si el bloque anónimo Y la función que estás usando usan los dos un argumento, +// puedes incluso omitir la barra baja. List("Dom", "Bob", "Natalia") foreach println -// Combinators -// Using `s` from above: +// Combinadores +// Usando s de arriba: // val s = Set(1, 3, 7) s.map(sq) -val sSquared = s. map(sq) +val sCuadrado = s. map(sq) sSquared.filter(_ < 10) sSquared.reduce (_+_) -// The filter function takes a predicate (a function from A -> Boolean) and -// selects all elements which satisfy the predicate +// La función filter toma un predicado (una función A -> Boolean) y +// selecciona todos los elementos que satisfacen el predicado. List(1, 2, 3) filter (_ > 2) // List(3) -case class Person(name: String, age: Int) +case class Persona(nombre: String, edad: Int) List( - Person(name = "Dom", age = 23), - Person(name = "Bob", age = 30) -).filter(_.age > 25) // List(Person("Bob", 30)) + Persona(nombre = "Dom", edad = 23), + Persona(nombre = "Bob", edad = 30) +).filter(_.edad > 25) // List(Persona("Bob", 30)) -// Certain collections (such as List) in Scala have a `foreach` method, -// which takes as an argument a type returning Unit - that is, a void method -val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100) -aListOfNumbers foreach (x => println(x)) -aListOfNumbers foreach println +// Ciertas colecciones (como List) en Scala tienen un método `foreach`, +// que toma como argumento un tipo que devuelva Unit (un método void) +val unaListaDeNumeros = List(1, 2, 3, 4, 10, 20, 100) +unaListaDeNumeros foreach (x => println(x)) +unaListaDeNumeros foreach println -// For comprehensions +// Para comprensiones for { n <- s } yield sq(n) -val nSquared2 = for { n <- s } yield sq(n) +val nCuadrado2 = for { n <- s } yield sq(n) for { n <- nSquared2 if n < 10 } yield n for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared -/* NB Those were not for loops. The semantics of a for loop is 'repeat', whereas - a for-comprehension defines a relationship between two sets of data. */ +/* Nota: Esos no son bucles. La semántica de un bucle es repetir, mientras que un for de comprension define una relación entre dos conjuntos de datos.*/ ///////////////////////////////////////////////// -// 8. Implicits +// 8. Implicitos ///////////////////////////////////////////////// -/* WARNING WARNING: Implicits are a set of powerful features of Scala, and - * therefore it is easy to abuse them. Beginners to Scala should resist the - * temptation to use them until they understand not only how they work, but also - * best practices around them. We only include this section in the tutorial - * because they are so commonplace in Scala libraries that it is impossible to - * do anything meaningful without using a library that has implicits. This is - * meant for you to understand and work with implicits, not declare your own. +/* ATENCIÓN ATENCIÓN: Los implicitos son un conjunto de poderosas características de Scala + * y es fácil abusar de ellos. Si eres principiante en Scala deberías resistir la tentación + * de usarlos hasta que entiendas no solo como funcionan, sino también las mejores prácticas + * con ellos. Nosotros solo incluiremos esta sección en el tutorial porque son tan comunes + * en las librerias de Scala que es imposible hacer algo significativo sin usar una librería + * que tenga implicitos. Esto es para que entiendas como funcionan los implicitos, no para + * que definas los tuyos propios. */ -// Any value (vals, functions, objects, etc) can be declared to be implicit by -// using the, you guessed it, "implicit" keyword. Note we are using the Dog -// class from section 5 in these examples. -implicit val myImplicitInt = 100 -implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed) - -// By itself, implicit keyword doesn't change the behavior of the value, so -// above values can be used as usual. -myImplicitInt + 2 // => 102 -myImplicitFunction("Pitbull").breed // => "Golden Pitbull" - -// The difference is that these values are now eligible to be used when another -// piece of code "needs" an implicit value. One such situation is implicit -// function arguments: -def sendGreetings(toWhom: String)(implicit howMany: Int) = - s"Hello $toWhom, $howMany blessings to you and yours!" - -// If we supply a value for "howMany", the function behaves as usual -sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!" - -// But if we omit the implicit parameter, an implicit value of the same type is -// used, in this case, "myImplicitInt": -sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!" - -// Implicit function parameters enable us to simulate type classes in other -// functional languages. It is so often used that it gets its own shorthand. The -// following two lines mean the same thing: +// Cualquier valor (val, funciones, objetos, etc) puede ser declarado como implicito usando +// la palabra "implicit". Observa que usamos la clase Perro de la sección 5. +implicit val miEnteroImplicito = 100 +implicit def miFunciónImplicita(raza: String) = new Perro("Golden " + raza) + +// Por si misma, la palabra implicit no cambia el comportamiento de un valor, +// así que estos valores pueden ser usados como siempre. +miEnteroImplicito + 2 // => 102 +miFunciónImplicita("Pitbull").raza // => "Golden Pitbull" + +// La diferencia es que estos valores ahora pueden ser usados cuando otra pieza de código +// necesite un valor implicito. Una situación así puede darse con argumentos implicitos de función: +def enviaSaludos(aQuien: String)(implicit cuantos: Int) = + s"Hola $aQuien, $cuantos saludos a ti y a los tuyos!" + +// Si proporcionamos un valor para "cuantos", la función se comporta como siempre +enviaSaludos("John")(1000) // => "Hola John, 1000 saludos a ti y a los tuyos!" + +// Pero si omitimos el parámetro implicito, un valor implicito del mismo tipo es usado, +// en este caso, "miEnteroImplicito": +enviaSaludos("Jane") // => "Hello Jane, 100 blessings to you and yours!" + +// Los parámetros de función implicit nos permiten simular clases tipo en otros lenguajes funcionales. +// Es usado tan a menudo que tiene su propio atajo. Las dos siguientes lineas significan lo mismo: // def foo[T](implicit c: C[T]) = ... // def foo[T : C] = ... -- cgit v1.2.3 From 34820c9323bc3cdb0709c01c114cc16fb62713d7 Mon Sep 17 00:00:00 2001 From: Pablo Date: Wed, 19 Jun 2019 11:17:05 +0200 Subject: finished translation --- es-es/scala-es.html.markdown | 76 +++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 40 deletions(-) (limited to 'es-es') diff --git a/es-es/scala-es.html.markdown b/es-es/scala-es.html.markdown index 355e74c5..2dcb9e7f 100644 --- a/es-es/scala-es.html.markdown +++ b/es-es/scala-es.html.markdown @@ -670,76 +670,72 @@ enviaSaludos("Jane") // => "Hello Jane, 100 blessings to you and yours!" // def foo[T : C] = ... -// Another situation in which the compiler looks for an implicit is if you have -// obj.method(...) -// but "obj" doesn't have "method" as a method. In this case, if there is an -// implicit conversion of type A => B, where A is the type of obj, and B has a -// method called "method", that conversion is applied. So having -// myImplicitFunction above in scope, we can say: -"Retriever".breed // => "Golden Retriever" -"Sheperd".bark // => "Woof, woof!" - -// Here the String is first converted to Dog using our function above, and then -// the appropriate method is called. This is an extremely powerful feature, but -// again, it is not to be used lightly. In fact, when you defined the implicit -// function above, your compiler should have given you a warning, that you -// shouldn't do this unless you really know what you're doing. - +// Otra situación en la que el compilador busca un implicit es si tienes +// obj.método(...) +// pero "obj" no tiene "método" como un método. En este caso, si hay una conversión +// implicita de tipo A => B, donde A es el tipo de obj y B tiene un método llamado +// "método", esa conversión es aplicada. Así que teniendo miFunciónImplicita, podemos decir: +"Retriever".raza // => "Golden Retriever" +"Sheperd".ladra // => "Woof, woof!" + +// Aquí la cadena es convertida primero a Perro usando nuestra función miFunciónImplicita, +// y entonces el método apropiado es llamado. Esta es una herramienta extremadamente poderosa +// pero de nuevo, no puede usarse con ligereza. De hecho, cuando definiste la función implicita, +// tu compilador debería haber mostrado una advertencia, diciendo que no deberías hacer esto +// a no ser que realmente sepas lo que estás haciendo. ///////////////////////////////////////////////// // 9. Misc ///////////////////////////////////////////////// -// Importing things +// Importando cosas import scala.collection.immutable.List -// Import all "sub packages" +// Importando todos los "sub paquetes" import scala.collection.immutable._ -// Import multiple classes in one statement +// Importando multiples clases en una línea import scala.collection.immutable.{List, Map} -// Rename an import using '=>' +// Renombrar un import usando '=>' import scala.collection.immutable.{List => ImmutableList} -// Import all classes, except some. The following excludes Map and Set: +// Importar todas las clases, excepto algunas. La siguiente linea excluye Map y Set: import scala.collection.immutable.{Map => _, Set => _, _} -// Java classes can also be imported. Scala syntax can be used +// Las clases de Java pueden ser importadas también con sintaxis de Scala: import java.swing.{JFrame, JWindow} -// Your programs entry point is defined in a scala file using an object, with a -// single method, main: +// El punto de entrada de tus programas está definido en un fichero scala usando un object, +// con un solo método, main: object Application { def main(args: Array[String]): Unit = { - // stuff goes here. + // Aquí va tu código. } } -// Files can contain multiple classes and objects. Compile with scalac - - +// Los ficheros pueden contener multiples clases y objetos. Compila con scalac -// Input and output +// Salida y entrada -// To read a file line by line +// Leer un fichero línea por línea import scala.io.Source -for(line <- Source.fromFile("myfile.txt").getLines()) +for(line <- Source.fromFile("miarchivo.txt").getLines()) println(line) -// To write a file use Java's PrintWriter -val writer = new PrintWriter("myfile.txt") -writer.write("Writing line for line" + util.Properties.lineSeparator) -writer.write("Another line here" + util.Properties.lineSeparator) +// Para escribir un archivo usa el PrintWriter de Java +val writer = new PrintWriter("miarchivo.txt") +writer.write("Escribiendo linea por linea" + util.Properties.lineSeparator) +writer.write("Otra linea" + util.Properties.lineSeparator) writer.close() ``` -## Further resources +## Más recursos -* [Scala for the impatient](http://horstmann.com/scala/) -* [Twitter Scala school](http://twitter.github.io/scala_school/) -* [The scala documentation](http://docs.scala-lang.org/) -* [Try Scala in your browser](http://scalatutorials.com/tour/) -* Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user) +* [Scala para los impacientes](http://horstmann.com/scala/) +* [Escuela de Scala en Twitter](http://twitter.github.io/scala_school/) +* [La documentación de Scala](http://docs.scala-lang.org/) +* [Prueba Scala en tu navegador](http://scalatutorials.com/tour/) +* Unete al [grupo de usuarios de Scala](https://groups.google.com/forum/#!forum/scala-user) -- cgit v1.2.3