Tutorial de Scala

โšก Resumen inteligente

El tutorial de Scala presenta un lenguaje de programaciรณn basado en la JVM, con tipado estรกtico, que combina la programaciรณn orientada a objetos y la programaciรณn funcional. La guรญa abarca la instalaciรณn, la sintaxis, las caracterรญsticas principales y los frameworks que hacen de Scala la herramienta ideal para crear aplicaciones modernas, concurrentes, escalables y concisas.

  • ๐Ÿ”˜ Paradigma hรญbrido: Scala fusiona la programaciรณn orientada a objetos y la programaciรณn funcional en la JVM, lo que permite a los desarrolladores combinar la inmutabilidad, las funciones de primera clase y las jerarquรญas de clases tradicionales.
  • โ˜‘๏ธ Sintaxis concisa: La inferencia de tipos, las funciones anรณnimas y la coincidencia de patrones reducen el cรณdigo repetitivo en comparaciรณn con Java mientras keeping El cรณdigo es expresivo y legible.
  • โœ… Configuraciรณn con IntelliJ: Instala el IDE Community Edition, aรฑade el plugin de Scala y crea un objeto que extienda App para ejecutar el primer programa Hello World.
  • ๐Ÿงช Componentes bรกsicos funcionales: La evaluaciรณn perezosa, el currying, las funciones de orden superior y la inmutabilidad mediante val dan como resultado un cรณdigo limpio y predecible.
  • ๐Ÿ› ๏ธ Concurrencia y marcos de trabajo: Actores de Akka, Futuros, Juego, Ascensor y Spark Esto convierte a Scala en una excelente opciรณn para sistemas distribuidos, aplicaciones web e ingenierรญa de datos.

Tutorial de Scala

ยฟQuรฉ es Scala?

Scala es un lenguaje de programaciรณn de tipado estรกtico que combina la programaciรณn orientada a objetos y la programaciรณn funcional para mejorar la escalabilidad de las aplicaciones. Scala se ejecuta principalmente en la plataforma JVM, y los desarrolladores tambiรฉn pueden usarlo para escribir software para plataformas nativas a travรฉs de Scala-Native, o para el navegador a travรฉs de ScalaJs y el JavaScript tiempo de ejecuciรณn.

Scala es un lenguaje escalable que se utiliza para construir software para mรบltiples plataformas, que es precisamente como obtuvo su nombre. El lenguaje fue diseรฑado para resolver varios de los problemas de verbosidad que se encuentran en Java Sin dejar de ser conciso. Martin Odersky diseรฑรณ Scala, y la primera versiรณn pรบblica apareciรณ en 2004.

ยฟPor quรฉ aprender Scala?

Estas son las principales razones para aprender el lenguaje de programaciรณn Scala:

  • Scala es fรกcil de aprender para los programadores orientados a objetos y Java desarrolladores, y se ha convertido en uno de los lenguajes mรกs populares en los รบltimos aรฑos.
  • Scala ofrece funciones de primera clase para los usuarios.
  • Scala se puede ejecutar en el JVMallanando el camino para la interoperabilidad con otros idiomas.
  • Estรก diseรฑado para aplicaciones concurrentes, distribuidas y resilientes basadas en mensajes, lo que lo convierte en uno de los lenguajes mรกs demandados de esta dรฉcada.
  • Es un lenguaje conciso y potente que puede evolucionar rรกpidamente segรบn las necesidades de sus usuarios.
  • Es un lenguaje orientado a objetos e incluye muchas caracterรญsticas de programaciรณn funcional, lo que brinda a los desarrolladores mucha flexibilidad en la forma en que escriben cรณdigo.
  • Scala ofrece Duck Typing a travรฉs de tipos estructurales.
  • Tiene menos texto estรกndar que Java.
  • Los frameworks Lift y Play, escritos en Scala, siguen madurando y ganando popularidad.

Cรณmo instalar Scala

Para empezar a escribir programas en Scala, necesitas tenerlo instalado en tu ordenador. Para ello, visita el sitio oficial en https://www.scala-lang.org/download/ para descargar la รบltima versiรณn de Scala.

Siguiendo el enlace, se le presentan dos opciones para instalar Scala. Para este tutorial de Scala, utilizaremos la IntelliJ IDEA, que proporciona un excelente soporte para Scala de forma predeterminada.

Cรณmo instalar Scala

Una vez que accedas al enlace de descarga, encontrarรกs dos ediciones del IDE IntelliJ.

Para este tutorial de Scala, descargaremos la ediciรณn Community Edition, que es gratuita e incluye todo lo necesario para escribir programas en Scala.

Pรกgina de descarga de IntelliJ Community Edition

Paso 1) Seleccione la ediciรณn comunitaria.
En la pรกgina, haga clic en el menรบ desplegable de la Ediciรณn Comunitaria.

Presenta una opciรณn para descargar el IDE IntelliJ junto con JBR, que contiene una implementaciรณn de JDK (Java Kit de desarrollo) como OpenJDK que Scala necesita para compilar y ejecutar cรณdigo.

Descarga IntelliJ con JBR

Paso 2) Ejecuta la instalaciรณn.
Una vez que descargue IntelliJ, haga doble clic en el instalador y siga el asistente que aparece en pantalla.

Asistente de instalaciรณn de IntelliJ

Paso 3) Selecciona una ubicaciรณn.
Elija una ubicaciรณn para instalar el IDE.

Seleccione la carpeta de instalaciรณn

Si no descargaste el paquete que incluye el JDK, el instalador te pedirรก igualmente que aรฑadas el JDK marcando una casilla durante la configuraciรณn.

Casilla de verificaciรณn de JDK durante la instalaciรณn

Paso 4) Haga clic en Siguiente.
Deje las demรกs opciones predeterminadas como estรกn y haga clic en Siguiente.

Opciones predeterminadas del instalador

Programa Scala Hola Mundo

Paso 5) Haz clic en el icono de inicio.
Una vez finalizada la instalaciรณn, ejecute el IDE IntelliJ haciendo clic en su icono de inicio en el menรบ Inicio, como si fuera una aplicaciรณn normal.

Pantalla de bienvenida de IntelliJ

Aรบn necesitas agregar el complemento de Scala a IntelliJ. Haz clic en el menรบ desplegable de configuraciรณn en la parte inferior derecha de la pantalla y selecciona la opciรณn Complementos.

Configurar menรบ para complementos

Mercado de plugins de IntelliJ

En la pestaรฑa Marketplace, busca Scala. El plugin aparece como el primer resultado bajo la etiqueta Languages.

Paso 6) Instale el complemento.
Haz clic en Instalar para comenzar la descarga del complemento de Scala.

Instalar el complemento Scala

Paso 7) Reinicia el IDE.
Una vez finalizada la descarga, se le pedirรก que reinicie el IDE para que el complemento instalado pueda comenzar a funcionar.

Reiniciar la consola de IntelliJ

Tras reiniciar, volverรกs a la misma pรกgina que antes, pero ahora el complemento de Scala estarรก instalado y listo.

Paso 8) Seleccione Crear proyecto, lo que le llevarรก a una pรกgina donde podrรก elegir el idioma del proyecto.

Crear un nuevo proyecto en IntelliJ

Paso 9) Seleccione Scala marcando la casilla de verificaciรณn de Scala y haga clic en Siguiente.

Seleccione el lenguaje Scala

Paso 10) Seleccione una ubicaciรณn para guardar el archivo del proyecto y asรญgnele un nombre.

Nombre y ubicaciรณn del proyecto

Si el directorio no existe, IntelliJ le pedirรก permiso para crear la carpeta. Acepte y haga clic en Finalizar. A continuaciรณn, accederรก a su proyecto Scala, que actualmente no contiene ningรบn cรณdigo Scala.

La carga de los รญndices lleva algo de tiempo, asรญ que no se preocupe si no puede interactuar con el IDE mientras se muestra una barra de progreso en la parte inferior. El IDE estรก cargando los archivos necesarios para ejecutar Scala y proporcionar la funciรณn de autocompletado.

Paso 11) Haz clic en la pestaรฑa Proyecto, situada a la izquierda del IDE, y expรกndela para ver el contenido del proyecto.

Expandir pestaรฑa del proyecto

En este punto, el proyecto estรก vacรญo y solo contiene una carpeta .idea y un archivo hello-world.iml generado por el IDE. Lo que nos interesa es la carpeta src, que contiene el cรณdigo fuente del proyecto. Aquรญ es donde se crea el primer archivo Scala.

Paso 12) Haz clic con el botรณn derecho en src para abrir un menรบ y crear un nuevo archivo Scala.

Crea un nuevo archivo Scala

Elige un nombre para el archivo. Para este tutorial de Scala, usa ยกHolaLuego, seleccione Objeto en el menรบ desplegable para el tipo de contenido del archivo Scala.

Seleccione el tipo de objeto

Una vez hecho esto, tendrรกs un archivo Scala que contiene un objeto singleton que utilizarรกs para ejecutar el cรณdigo.

Objeto Singleton creado

Ahora que tienes un archivo Scala con un objeto Hello, escribe tu primer programa extendiendo el objeto que creaste usando la palabra clave App.

Al extender el objeto con App, se le indica al compilador quรฉ cรณdigo debe ejecutar al iniciar el programa. Inmediatamente despuรฉs de extender App, aparece una flecha verde en el lado izquierdo, lo que indica que el programa ya se puede ejecutar.

Ejecutar flecha en IntelliJ

Ejecutar la opciรณn Hola

Dentro del objeto Hello, escribe la funciรณn println() para imprimir el texto en la consola. Ejecuta el programa haciendo clic en la flecha verde.

Al hacer clic en la flecha, aparece la opciรณn Ejecutar Hello. Al seleccionarla, se compila el cรณdigo y, tras unos segundos, la salida del programa aparece en la consola de IntelliJ.

Salida de "Hola mundo" en la consola

Ya has instalado Scala correctamente y has ejecutado tu primer programa.

Quรฉ puedes hacer con Scala

Scala se utiliza ampliamente en muchos รกmbitos debido a su flexibilidad e interoperabilidad con la JVM. Algunos casos de uso comunes son:

  • Desarrollo web frontend con ScalaJS.
  • Desarrollo mรณvil para Android y iOS con Scala Native.
  • Bibliotecas del lado del servidor como HTTP4S, Akka-Http y Play Framework.
  • Aplicaciones del Internet de las Cosas (IoT).
  • Desarrollo de juegos.
  • Procesamiento del lenguaje natural mediante el conjunto de bibliotecas ScalaNLP.
  • Practicar conjuntamente tรฉcnicas avanzadas como la programaciรณn funcional y la programaciรณn orientada a objetos.
  • Aplicaciones de comunicaciรณn altamente concurrentes que utilizan actores, una biblioteca para la JVM inspirada en Erlang.
  • Aprendizaje automรกtico con bibliotecas como Figaro para programaciรณn probabilรญstica y Apache Spark para el procesamiento de datos a gran escala.

Funciones anรณnimas

El lenguaje Scala admite funciones anรณnimas, tambiรฉn llamadas literales de funciรณnDebido a que Scala es un lenguaje funcional, los desarrolladores a menudo dividen los problemas grandes en muchas tareas pequeรฑas y crean muchas funciones. Para facilitar esto, Scala permite que las funciones sean... instanciado sin nombrePuedes asignarlos directamente a variables o a definiciones usando def, como se muestra en el siguiente ejemplo de Scala:

val multiplyByTwo = (n:Int) => n * 2
def multiplyByThree = (n:Int) => n * 3

Luego puedes utilizarlas como funciones normales pasรกndoles parรกmetros:

multiplyByTwo(3)
//6

multiplyByThree(4)
//12

Estos mรฉtodos resultan muy รบtiles cuando se busca un cรณdigo limpio y conciso. Las funciones anรณnimas son prรกcticas para definir mรฉtodos pequeรฑos que no requieren mucho cรณdigo. Son muy sencillas y su creaciรณn es muy rรกpida.

Estos mรฉtodos no se limitan a funciones con argumentos y pueden utilizarse para instanciar mรฉtodos que no requieren argumentos.

val sayHello = () => { println("hello") }

La mayorรญa de estas funciones anรณnimas se utilizan en otras partes del cรณdigo donde se necesita una funciรณn rรกpida. Por esta razรณn, tambiรฉn se las conoce como funciones en lรญneaEl uso de funciones anรณnimas es un patrรณn comรบn que aparece en toda la biblioteca de colecciones para realizar acciones rรกpidas sobre una colecciรณn.

Por ejemplo, el mรฉtodo filter utiliza una funciรณn en lรญnea para crear otra colecciรณn con solo los elementos que cumplen los criterios definidos en la funciรณn anรณnima.

val myList = List(1,2,3,4,5,6,7)

val myEvenList = myList.filter((n: Int) => n % 2 == 0)
//List(2,4,6)

val myOddList = myList.filter((n:Int) => n % 2 != 0)
//List(1,3,5,7)

Aquรญ, las funciones anรณnimas comprueban si el valor de la lista es par o impar y devuelven el elemento correspondiente.

//the one checking that the value is even
(n: Int) => n % 2 == 0

//the one checking that the value is odd
(n:Int) => n % 2 != 0

En Scala, tambiรฉn es posible usar comodines cuando el parรกmetro de la funciรณn anรณnima no tiene nombre. Por ejemplo:

var timesTwo = (_:Int) * 2

timesTwo(5)
//10

En este caso, no se especifica el nombre del parรกmetro. Se utiliza el guion bajo para representarlo.

Evaluaciรณn perezosa

La mayorรญa de los lenguajes evalรบan secuencialmente las variables y los parรกmetros de las funciones, uno tras otro. En Scala, la palabra clave lazy Ayuda a lidiar con valores que no se desean evaluar hasta que se hace referencia a ellos.

Una variable marcada como lazy no se evalรบa en el lugar donde se define, lo que se conoce comรบnmente como evaluaciรณn eager. Solo se evalรบa cuando se hace referencia a ella mรกs adelante en el cรณdigo.

Esto puede ser รบtil cuando evaluar un valor implicarรญa un cรกlculo costoso. Si el valor no siempre es necesario, se evita realizar un cรกlculo costoso que puede ralentizar el software al hacer que la variable sea de evaluaciรณn diferida.

lazy val myExpensiveValue = expensiveComputation

def runMethod() = {
    if(settings == true) {
        use(myExpensiveValue)
    } else {
        use(otherValue)
    }
}

Este no es el รบnico caso de uso para las variables perezosas. Tambiรฉn ayudan a lidiar con dependencias circulares en el cรณdigo.

Si el indicador de configuraciรณn es falso, no es necesario usar myExpensiveValue, lo que evita realizar un cรกlculo costoso. Esto ayuda a garantizar una experiencia fluida para los usuarios, ya que no se desperdician recursos en valores que nunca se leen.

La evaluaciรณn perezosa tambiรฉn resulta รบtil con los argumentos de las funciones, ya que estos solo se utilizan cuando se hace referencia a ellos dentro de la funciรณn. Este concepto se denomina parรกmetros por nombre.

def sometimesUsedString(someValue:String, defaultValue: => String) = {
 if(someValue != null) {
   use(defaultValue)
 } else {
   use(someValue)
   }
 }

Muchos lenguajes utilizan el mรฉtodo de paso por valor para evaluar los argumentos. Un parรกmetro pasado por nombre solo se evalรบa cuando es necesario dentro del cuerpo de la funciรณn. Una vez evaluado el valor, se almacena y puede reutilizarse posteriormente sin necesidad de reevaluarlo, un concepto conocido como memorizaciรณn.

Inferencia de tipo

En Scala, no es necesario declarar el tipo de cada variable que se crea, ya que el compilador de Scala puede inferirlo a partir del lado derecho de una expresiรณn. Esto permite que el cรณdigo sea mรกs conciso y evita tener que escribir cรณdigo repetitivo donde el tipo esperado es obvio.

var first:String = "Hello, "
var second:String = "World"
var third = first + second
//the compiler infers that third is of type String

Funciรณn de orden superior

Una funciรณn de orden superior es aquella que puede recibir funciones como argumentos y devolver una funciรณn como tipo de retorno. En Scala, las funciones se consideran elementos de primera clase. Usarlas de esta manera permite una gran flexibilidad en el tipo de programas que se pueden construir. Se pueden crear funciones dinรกmicamente y proporcionar funcionalidad a otras funciones de forma dinรกmica.

def doMathToInt(n:Int, myMathFunction:Int=>Int): Int = {
    myMathFunction(n)
}

En la funciรณn anterior, se pasa un Int y una funciรณn que toma un Int y devuelve un Int. Puedes pasar cualquier funciรณn de esa firma. Por firma, nos referimos a la entrada y salida de una funciรณn. Una firma de Int => Int significa que una funciรณn toma un entero como entrada y devuelve un entero como salida.

Una firma de () => Int Esto significa que una funciรณn no recibe ninguna entrada y devuelve un entero como salida. Un ejemplo de dicha funciรณn es una que genera un entero aleatorio.

def generateRandomInt() = {
 return scala.util.Random.nextInt()
}

La funciรณn anterior tiene una firma () => Int.

Una funciรณn tambiรฉn puede tener una firma. () => UnitEsto significa que la funciรณn no recibe ningรบn parรกmetro y no devuelve ningรบn tipo de dato. En su lugar, la funciรณn puede modificar algรบn estado o realizar una acciรณn predeterminada.

Este tipo de mรฉtodos no son recomendables porque pueden actuar como una caja negra que afecta al sistema de maneras desconocidas. Ademรกs, son mรกs difรญciles de probar. Especificar los tipos de entrada y salida permite comprender el funcionamiento de la funciรณn.

Una funciรณn de orden superior tambiรฉn puede devolver otra funciรณn. Por ejemplo, se podrรญa crear un mรฉtodo que devuelva una funciรณn de potenciaciรณn, es decir, una que tome un nรบmero y le aplique una potencia.

def powerByFunction(n:Int): Int=>Int = {
  return (x:Int) => scala.math.pow(x,n).toInt
}

La funciรณn anterior recibe un Int. Su tipo de retorno es una funciรณn anรณnima que recibe un Int. x y lo utiliza como argumento para la funciรณn de potencia.

Zurra

En Scala, puedes convertir una funciรณn que recibe dos argumentos en una que recibe uno a la vez. Al pasar un argumento, este se aplica parcialmente y la funciรณn resultante recibe el argumento restante para completar la llamada. El currying te permite construir funciones aรฑadiendo parcialmente algunos argumentos.

Esto resulta รบtil para crear funciones de forma dinรกmica antes de tener un conjunto completo de argumentos.

def multiplyTwoNumbers(n:Int)(m:Int): Int = {
  return n * m
}

Si necesitas una funciรณn que multiplique por un nรบmero especรญfico, no necesitas crear otro mรฉtodo de multiplicaciรณn. Puedes aplicar un argumento a la funciรณn currificada y reutilizar el resultado:

def multiplyTwoNumbers(n:Int)(m:Int): Int = {
  return n * m
}

var multiplyByFive = multiplyTwoNumbers(5) _

multiplyByFive(4)

//returns 20

La coincidencia de patrones

Scala tiene un potente mecanismo incorporado que te ayuda a comprobar si una variable coincide con ciertos criterios, de forma muy similar a una sentencia switch. Java o una cadena de sentencias if/else. El lenguaje admite la coincidencia de patrones, que puede utilizar para comprobar si una variable es de un tipo particular. La coincidencia de patrones en Scala es potente y puede desestructurar componentes que tienen un unapply Mรฉtodo para obtener los campos que le interesan directamente de la variable que se estรก comparando.

La coincidencia de patrones en Scala tambiรฉn proporciona una sintaxis mรกs agradable que una sentencia switch.

myItem match {
  case true => //do something
  case false => //do something else
  case  _ => //if none of the above do this by default
}

Se compara la variable con un conjunto de opciones. Cuando la variable cumple los criterios, la expresiรณn situada a la derecha de la flecha gruesa (=>) se evalรบa y devuelve el resultado de la coincidencia.

El guion bajo detecta los casos que no coinciden en el cรณdigo, reflejando el comportamiento del caso predeterminado en una instrucciรณn switch.

class Animal(var legs:Int, var sound:String)
class Furniture(var legs:Int, var color:Int, var woodType:String)

myItem match {
case myItem:Animal => //do something
case myItem:Furniture => //do something else
case _ => //unknown type, do something else
}

En el cรณdigo anterior, puedes detectar el tipo de myItem variable y, en funciรณn de eso, ramificarse a cรณdigo especรญfico.

La coincidencia de patrones comprueba si la variable coincide con cada caso en orden.

El guion bajo funciona como un marcador de posiciรณn que coincide con cualquier condiciรณn que las otras sentencias case no cumplan. Se toma una variable. myItem y llama al match mรฉtodo.

  • Compruebe si myItem is true y ejecuta la lรณgica del lado derecho de la flecha gruesa โ€œ=>โ€.
  • Utilice el guion bajo para que coincida con todo aquello que no coincida con ninguna de las sentencias case definidas en el cรณdigo.

Con las clases de caso, puedes desestructurar la clase para extraccampos t dentro del objeto.

Mediante el uso de la sealed Al usar la palabra clave para definir clases, obtienes el beneficio de que el compilador revise exhaustivamente los casos que intentas hacer coincidir y te avise si olvidas manejar alguno.

Inmutabilidad

Es posible crear valores que no pueden ser modificados por otras funciones en Scala mediante el uso de val palabra clave. Esto se logra en Java mediante el uso de la final palabra clave. En Scala, se utiliza una val al crear una variable en lugar de var, que es la alternativa para variables mutables.

Una variable definida mediante el val La palabra clave es de solo lectura, mientras que una definida con var Puede ser leรญdo y modificado posteriormente por otras funciones o por el usuario en el cรณdigo.

var changeableVariable = 8

changeableVariable = 10
//the compiler does not complain, and the code compiles successfully

println(changeableVariable)
//10

val myNumber = 7

myNumber = 4

//this will not compile

Intentando asignar un valor a myNumber despuรฉs de declararlo como un val genera un error de compilaciรณn: โ€œreasignaciรณn a valโ€.

ยฟPor quรฉ utilizar la inmutabilidad?

La inmutabilidad ayuda a evitar que el cรณdigo y otros programadores modifiquen valores inesperadamente, lo que podrรญa generar resultados impredecibles. Si quienes utilizan un valor necesitan modificarlo, pueden crear una copia. De esta forma, se evitan errores causados โ€‹โ€‹por mรบltiples usuarios que modifican la misma variable.

Clases y objetos

Los objetos son entidades del mundo real, y una clase es una plantilla que define objetos. Las clases tienen estado y comportamiento. El estado puede ser un valor o una variable. El comportamiento son los mรฉtodos en Scala.

La siguiente secciรณn muestra cรณmo definir una clase, instanciarla y usarla en Scala.

Aquรญ hay una clase llamada Rectรกngulo que tiene dos valores y dos funciones. Tambiรฉn puede usar los parรกmetros. l y b directamente como campos en el programa. Tienes un objeto que tiene un mรฉtodo principal e instancia la clase con dos valores.

Ejemplo:

class Rectangle(l: Int, b: Int) {
  val length: Int = l
  val breadth: Int = b
  def getArea: Int = l * b
  override def toString = s"This is a rectangle with length $length and breadth $breadth"
}
object RectObject {
  def main(args: Array[String]) {
    val rect = new Rectangle(4, 5)
    println(rect.toString)
    println(rect.getArea)
  }
}

Todos los campos y mรฉtodos son pรบblicos por defecto en Scala. Es esencial utilizar override because toString ya estรก definido para cada objeto en Scala.

Herencia

Scala tiene varios tipos de herencia (simple, multinivel, mรบltiple, jerรกrquica e hรญbrida) que comparten mucho en comรบn con las formas tradicionales que se encuentran en JavaPuedes heredar tanto de clases como de rasgos. Heredas los miembros de una clase en otra clase usando la palabra clave extendsEsto permite la reutilizaciรณn.

Es posible heredar de una o varias clases. Tambiรฉn es posible heredar de subclases que, a su vez, tienen sus propias superclases, creando asรญ una jerarquรญa de herencia.

En el ejemplo de Scala que se muestra a continuaciรณn, la clase base es Circley la clase derivada es Sphere. Un cรญrculo tiene un valor llamado radio, que se hereda en la clase Esfera. El mรฉtodo calcArea se anula usando la palabra clave override.

Ejemplo:

class Circle {
  val radius = 5
  def calcArea = {
    println(radius * radius)
  }
}
class Sphere extends Circle {
 override def calcArea = {
    println(radius * radius * radius)
  }
}
  object SphereObject {
    def main(args : Array[String]) {
      new Sphere().calcArea
    }
  }

Abstracdisrupciรณn

En Scala, puedes crear abstracmรฉtodos t y campos miembros usando abstracclases y rasgos t. Dentro de los abdominalestracclases y rasgos, puedes definir abstraccampos t sin implementarlos.

Ejemplo:

trait MakesSound {
    var nameOfSound:String
    def sound():String
}
abstract class HasLegs(var legs:Int) {
    val creatureName:String

    def printLegs():String = {
        return s"$creatureName has this number of legs: $legs"
    }
}

Estos campos son implementados por las clases que extienden el rasgo o abstracclase t. Puedes usar rasgos para crear contracts para lo que una aplicaciรณn deberรญa hacer y luego implementar esos mรฉtodos mรกs adelante.

trait DatabaseService {
    def addItemName(itemName:String)
    def removeItem(itemId:Int)
    def updateItem(itemId:Int, newItemName:String)
}

De esta forma, puedes planificar cรณmo se verรก una aplicaciรณn sin implementar los mรฉtodos, ayudaping Visualizas cรณmo aparecerรกn los distintos mรฉtodos. Sigue un patrรณn conocido como programaciรณn para abs.tracciones mรกs que a la implementaciรณn real.

Una clase precedida por el abstract La palabra clave puede contener ambos abstract y no abstracmรฉtodos t. Sin embargo, la herencia mรบltiple no es compatible con abstracclases t, por lo que solo puedes extender un abstracclase t.

Objetos Singleton

Un singleton es una clase que se instancia solo una vez en un programa. Proviene de un patrรณn de programaciรณn popular y รบtil conocido como el "patrรณn singleton". Es รบtil para crear instancias que estรกn destinadas a ser de larga duraciรณn y a las que se accede comรบnmente a lo largo del programa, donde el estado es integral para coordinar eventos en un sistema. Crear una clase de este tipo en Scala es fรกcil porque Scala proporciona un medio simple para crear singletons usando el object palabra clave.

object UserProfile {
    var userName = ""
    var isLoggedIn:Boolean = false
}

A continuaciรณn, puede hacer referencia a este objeto en todo el programa con la garantรญa de que todas las partes del programa verรกn los mismos datos, ya que solo existe una instancia del mismo.

def getLoggedInStatus():Boolean = {
   return UserProfile.isLoggedIn
}

def changeLoggedInStatus():Boolean = {
    UserProfile.isLoggedIn = !UserProfile.isLoggedIn
    return UserProfile.isLoggedIn
}

En Scala no existe el concepto de miembros estรกticos, por lo que se utilizan objetos singleton que actรบan como miembros estรกticos de una clase.

Clases implรญcitas

Las clases implรญcitas son una caracterรญstica aรฑadida en la versiรณn 2.10 y se utilizan principalmente para agregar nueva funcionalidad a las clases cerradas existentes.

El implicit La palabra clave debe estar definida en una clase, objeto o rasgo. El constructor principal de una clase implรญcita debe tener exactamente un argumento en su primera lista de parรกmetros. Tambiรฉn puede incluir una lista de parรกmetros implรญcitos adicional.

En el siguiente ejemplo de Scala, se agrega una nueva funcionalidad para reemplazar las vocales de una cadena con *.

object StringUtil {
  implicit class StringEnhancer(str: String) {

    def replaceVowelWithStar: String = str.replaceAll("[aeiou]", "*")
  }
}

Debes importar la clase implรญcita en la clase donde la estรฉs utilizando.

import StringUtil.StringEnhancer

object ImplicitEx extends App {
  val msg = "This is Guru99!"
  println(msg.replaceVowelWithStar)
}

Programaciรณn Orientada a Objetos (POO) frente a Programaciรณn Funcional (PF)

En la POO, los programas se construyen mediante grupos.ping Los datos y las funciones que operan sobre esos datos se convierten en unidades altamente conectadas. Los objetos contienen sus datos en campos y los mรฉtodos operan sobre ellos. En este estilo de programaciรณn, el elemento principal es el abs.tracLa base son los datos, porque los mรฉtodos que se crean estรกn diseรฑados para operar sobre ellos.

Programaciรณn funcionalPor otro lado, separa los datos y las funciones que operan sobre ellos. Esto permite a los desarrolladores tratar las funciones como los datos absolutos.tracciรณn y fuerza impulsora al modelar programas.

Scala posibilita la programaciรณn funcional al tratar las funciones como elementos de primera clase, permitiendo que se pasen como valores a otras funciones y que tambiรฉn se devuelvan como valores. La combinaciรณn de estos dos paradigmas ha convertido a Scala en una excelente opciรณn para desarrollar software complejo en sectores como la ciencia de datos.

Marcos importantes en Scala

Aquรญ tienes algunos frameworks importantes para Scala:

  • Jugar es un marco de aplicaciรณn web de cรณdigo abierto que utiliza Arquitectura MVCLanzado en 2007 y ahora con licencia Apache, se convirtiรณ en uno de los frameworks mรกs populares en GitHub para 2013. Empresas como LinkedIn, WalmartSamsung y Eero utilizan este marco.
  • Lift es otro framework web gratuito escrito en Scala, lanzado en 2007. Foursquare utiliza el framework Lift. Es un framework de alto rendimiento que permite un desarrollo rรกpido.
  • Acre Proporciona un conjunto de herramientas para crear aplicaciones basadas en mensajes, altamente concurrentes, distribuidas y resilientes en la JVM.
  • Gatos - Leecork es una biblioteca que proporciona abstracciones para la programaciรณn funcional.
  • Spark Es un motor de anรกlisis unificado para el procesamiento de datos a gran escala, ampliamente utilizado en flujos de trabajo de big data y aprendizaje automรกtico.

Soporte de concurrencia

  • En Scala, los valores son inmutables por defecto, lo que lo hace muy adaptable a entornos concurrentes.
  • Scala posee muchas caracterรญsticas que lo hacen ideal para aplicaciones concurrentes.
  • Los futuros y las promesas facilitan el procesamiento de datos de forma asincrรณnica, lo que favorece el paralelismo.
  • Akka es un conjunto de herramientas que utiliza el modelo de concurrencia de actores. Los actores actรบan cuando reciben mensajes.
  • Concurrencia usando hilos de Java Tambiรฉn es compatible con Scala.
  • El procesamiento de flujos de datos es otra gran caracterรญstica que permite el procesamiento continuo y en tiempo real de los datos.

Scala tiene algunas de las mejores bibliotecas de concurrencia del mundo. Java ecosistema:

  • Nativo Java roscas.
  • Fibras de bibliotecas como Vertx.
  • ZIO es una biblioteca que contiene funciones bรกsicas para ayudar a gestionar la concurrencia y la computaciรณn asรญncrona.
  • Memoria transaccional de software (STM) para transacciones.
  • Future, que estรก integrado en el lenguaje Scala.

Java contra Scala

Aquรญ estรกn los principales diferencias entre Java y escala.

Scala Java
Mรกs compacto y conciso. Fragmentos de cรณdigo comparativamente mรกs grandes.
Diseรฑado y desarrollado para ser tanto orientado a objetos como funcional. Admite una amplia variedad de caracterรญsticas de programaciรณn funcional, como la concurrencia y la inmutabilidad. Originalmente desarrollado como un lenguaje orientado a objetos, comenzรณ a admitir caracterรญsticas de programaciรณn funcional en versiones recientes. Sin embargo, aรบn no es tan potente como Scala para la programaciรณn funcional.
Utiliza el modelo de actores para admitir la concurrencia. Utiliza el modelo convencional basado en subprocesos para la concurrencia.
Admite marcos de trabajo como Play y Lift. Compatible con Spring, Grails y muchos mรกs.
Admite la evaluaciรณn perezosa. No admite la evaluaciรณn perezosa de forma nativa.
No hay miembros estรกticos. Contiene miembros estรกticos.
Admite la sobrecarga del operador. No admite la sobrecarga de operadores.
La compilaciรณn del cรณdigo fuente es relativamente lenta. La compilaciรณn del cรณdigo fuente es mรกs rรกpida que con Scala.
Los rasgos actรบan como Java 8 interfaces. Java Ocho interfaces intentan salvar la brecha entre clases e interfaces.
En ocasiones, es necesario reescribir el cรณdigo al actualizar versiones. Por lo general, no es necesario reescribir el texto entre versiones.
La seguridad de tipos proporciona una gran fiabilidad al cรณdigo, pero no una garantรญa absoluta de que estรฉ libre de errores. Fuerte estรกtica typing ayuda a reducir muchos defectos en tiempo de ejecuciรณn.
Presenta algunas limitaciones de compatibilidad con versiones anteriores entre las principales versiones. Fuerte compatibilidad retroactiva a largo plazo.
OperaLos tors se tratan como llamadas a mรฉtodos. OperaLos tors son una sintaxis especial y no son llamadas a mรฉtodos.
Admite herencia mรบltiple mediante rasgos. No admite la herencia mรบltiple mediante clases; en su lugar, utiliza interfaces.
Code Estรก escrito de forma concisa. Code estรก escrito de forma mรกs prolija.
Scala no contiene la palabra clave estรกtica. Java contiene la palabra clave estรกtica.

Preguntas Frecuentes

Scala tiene una curva de aprendizaje mรกs pronunciada que Java porque combina estilos orientados a objetos y funcionales. Sin embargo, los desarrolladores con Java La experiencia suele permitir asimilar rรกpidamente los conceptos bรกsicos. Practicar con proyectos pequeรฑos y la consola interactiva de Scala acelera el aprendizaje.

Sรญ. Scala sigue impulsando sistemas a gran escala en empresas que utilizan Akka, Sparky Kafka. La demanda sigue siendo alta en ingenierรญa de datos, tecnologรญa financiera y sistemas distribuidos, donde el rendimiento de la JVM y la programaciรณn funcional son valiosos.

Sรญ. Los asistentes de codificaciรณn de IA modernos entienden la sintaxis de Scala, el sistema de tipos y los marcos como Akka y SparkAyudan a generar cรณdigo repetitivo, sugieren patrones funcionales, explican errores de compilaciรณn y refactorizan el cรณdigo, acelerando el desarrollo tanto para principiantes como para expertos.

Scala impulsa Apache SparkScala es el motor lรญder para el procesamiento de datos a gran escala en pipelines de IA. Bibliotecas como Breeze, Smile y Figaro admiten computaciรณn numรฉrica, aprendizaje automรกtico y modelado probabilรญstico, lo que convierte a Scala en una excelente opciรณn para la ciencia de datos en producciรณn.

Un `val` crea una vinculaciรณn inmutable que se evalรบa inmediatamente. Un `var` crea una vinculaciรณn mutable que se puede reasignar. Un `lazy val` pospone la evaluaciรณn hasta que se accede al valor por primera vez y luego almacena en cachรฉ el resultado para lecturas posteriores.

Resumir este post con: