Tutorial Scala

โšก Resumo Inteligente

O Tutorial de Scala apresenta uma linguagem estaticamente tipada, baseada na JVM, que une programaรงรฃo orientada a objetos e programaรงรฃo funcional. O guia aborda instalaรงรฃo, sintaxe, recursos principais e frameworks que tornam o Scala ideal para a criaรงรฃo de aplicaรงรตes modernas, concorrentes, escalรกveis โ€‹โ€‹e concisas.

  • ๐Ÿ”˜ Paradigma Hรญbrido: Scala combina programaรงรฃo orientada a objetos e programaรงรฃo funcional na JVM, permitindo que os desenvolvedores combinem imutabilidade, funรงรตes de primeira classe e hierarquias de classes tradicionais.
  • โ˜‘๏ธ Sintaxe concisa: A inferรชncia de tipos, funรงรตes anรดnimas e correspondรชncia de padrรตes reduzem o cรณdigo repetitivo em comparaรงรฃo com Java enquanto keeping O cรณdigo deve ser expressivo e legรญvel.
  • โœ… Configuraรงรฃo com o IntelliJ: Instale a IDE Community Edition, adicione o plugin Scala e crie um objeto que estenda App para executar o primeiro programa "Olรก, Mundo!".
  • ๐Ÿงช Blocos de construรงรฃo funcionais: Avaliaรงรฃo preguiรงosa, currying, funรงรตes de ordem superior e imutabilidade por meio de val permitem a criaรงรฃo de cรณdigo limpo e previsรญvel.
  • ๐Ÿ› ๏ธ Concorrรชncia e Frameworks: Atores Akka, Futuros, Brincar, Levantar e Spark Isso faz do Scala uma excelente escolha para sistemas distribuรญdos, aplicaรงรตes web e engenharia de dados.

Tutorial Scala

O que รฉ Escala?

Scala Scala รฉ uma linguagem de programaรงรฃo estaticamente tipada que combina programaรงรฃo orientada a objetos e programaรงรฃo funcional para melhorar a escalabilidade de aplicaรงรตes. Scala roda principalmente na plataforma JVM, e desenvolvedores tambรฉm podem usรก-la para escrever software para plataformas nativas atravรฉs do Scala-Native, ou para o navegador atravรฉs do ScalaJS e do Scala.js. JavaScript tempo de execuรงรฃo.

Scala รฉ uma linguagem escalรกvel usada para construir software para mรบltiplas plataformas, o que explica seu nome. A linguagem foi projetada para resolver diversos problemas de verbosidade encontrados em... Java mantendo-se concisa. Martin Odersky projetou o Scala, e a primeira versรฃo pรบblica foi lanรงada em 2004.

Por que aprender Scala

Aqui estรฃo os principais motivos para aprender a linguagem de programaรงรฃo Scala:

  • Scala รฉ fรกcil de aprender para programadores orientados a objetos e Java desenvolvedores, e se tornou uma das linguagens populares nos รบltimos anos.
  • Scala oferece funรงรตes de primeira classe para os usuรกrios.
  • Scala pode ser executado em JVM, abrindo caminho para a interoperabilidade com outros idiomas.
  • Ela foi projetada para aplicaรงรตes concorrentes, distribuรญdas e resilientes, orientadas a mensagens, o que a torna uma das linguagens mais requisitadas desta dรฉcada.
  • ร‰ uma linguagem concisa e poderosa que pode crescer rapidamente de acordo com a demanda de seus usuรกrios.
  • ร‰ orientada a objetos e inclui muitos recursos de programaรงรฃo funcional, oferecendo aos desenvolvedores muita flexibilidade na forma como escrevem o cรณdigo.
  • Scala oferece Duck Typing por meio de tipos estruturais.
  • Tem menos texto padrรฃo do que Java.
  • Os frameworks Lift and Play, escritos em Scala, continuam a amadurecer e a ganhar popularidade.

Como instalar Scala

Para comeรงar a escrever programas em Scala, vocรช precisa tรช-lo instalado em seu computador. Para fazer isso, visite o site oficial em https://www.scala-lang.org/download/ Para baixar a versรฃo mais recente do Scala.

Ao acessar o link, vocรช encontrarรก duas opรงรตes para instalar o Scala. Para este tutorial de Scala, usaremos a primeira opรงรฃo. IntelliJ IDEA, que oferece excelente suporte a Scala logo de inรญcio.

Como instalar Scala

Ao acessar o link de download, vocรช encontrarรก duas ediรงรตes do IntelliJ IDE.

Para este tutorial de Scala, vamos baixar a Community Edition, que รฉ gratuita e inclui tudo o que vocรช precisa para escrever programas em Scala.

Pรกgina de download da IntelliJ Community Edition

Passo 1) Selecione a Ediรงรฃo Comunitรกria.
Na pรกgina, clique no menu suspenso da Ediรงรฃo Comunitรกria.

Ele oferece a opรงรฃo de baixar o IntelliJ IDE juntamente com o JBR, que contรฉm uma implementaรงรฃo do JDK (Java Kit de Desenvolvimento (Development Kit), como o OpenJDK, que o Scala precisa para compilar e executar cรณdigo.

Baixe o IntelliJ com JBR

Passo 2) Execute a instalaรงรฃo.
Apรณs baixar o IntelliJ, clique duas vezes no instalador e siga o assistente na tela.

Assistente de instalaรงรฃo do IntelliJ

Passo 3) Selecione um local.
Escolha um local para instalar o IDE.

Selecione a pasta de instalaรงรฃo

Se vocรช nรฃo baixou o pacote com o JDK, o instalador ainda solicitarรก que vocรช adicione o JDK por meio de uma caixa de seleรงรฃo durante a instalaรงรฃo.

Marque a caixa de seleรงรฃo JDK durante a instalaรงรฃo.

Passo 4) Clique em Avanรงar.
Deixe as outras configuraรงรตes padrรฃo como estรฃo e clique em Avanรงar.

Opรงรตes padrรฃo do instalador

Programa Scala Olรก Mundo

Passo 5) Clique no รญcone de inicializaรงรฃo.
Apรณs a conclusรฃo da instalaรงรฃo, execute o IntelliJ IDE clicando no รญcone de inicializaรงรฃo no menu Iniciar, como faria com qualquer outro aplicativo.

Tela de boas-vindas do IntelliJ

Vocรช ainda precisa adicionar o plugin Scala ao IntelliJ. Clique no menu suspenso de configuraรงรฃo no canto inferior direito da tela e selecione a opรงรฃo Plugins.

Menu de configuraรงรฃo para plugins

Mercado de plugins do IntelliJ

Na aba Marketplace, procure por Scala. O plugin aparecerรก como o primeiro resultado na categoria Idiomas.

Passo 6) Instale o plugin.
Clique em Instalar para iniciar o download do plugin Scala.

Instale o plugin Scala

Passo 7) Reinicie a IDE.
Apรณs a conclusรฃo do download, vocรช serรก solicitado a reiniciar a IDE para que o plugin instalado possa comeรงar a funcionar.

Reinicie o prompt do IntelliJ

Apรณs reiniciar, vocรช retorna ร  mesma pรกgina de antes, mas agora o plugin Scala estรก instalado e pronto para uso.

Passo 8) Selecione "Criar projeto", que o levarรก a uma pรกgina onde vocรช poderรก escolher o idioma do projeto.

Criar novo projeto no IntelliJ

Passo 9) Selecione Scala marcando a caixa de seleรงรฃo Scala e clique em Avanรงar.

Selecione a linguagem Scala

Passo 10) Selecione um local para salvar o arquivo do projeto e dรช um nome ao projeto.

Nomeie e localize o projeto

Se o diretรณrio nรฃo existir, o IntelliJ solicitarรก permissรฃo para criar a pasta. Aceite e clique em Concluir. Vocรช serรก entรฃo direcionado para o seu projeto Scala, que atualmente nรฃo contรฉm nenhum cรณdigo Scala.

O carregamento dos รญndices leva algum tempo, portanto, nรฃo se preocupe se nรฃo conseguir interagir com a IDE enquanto uma barra de progresso รฉ exibida na parte inferior. A IDE estรก carregando os arquivos necessรกrios para executar o Scala e fornecer o recurso de autocompletar.

Passo 11) Clique na aba Projeto, ร  esquerda da IDE, e expanda-a para visualizar o conteรบdo do projeto.

Expandir aba do projeto

Neste ponto, o projeto estรก vazio e contรฉm apenas uma pasta .idea e um arquivo hello-world.iml gerado pela IDE. O ponto de interesse รฉ a pasta src, que contรฉm o cรณdigo-fonte do projeto. ร‰ aqui que vocรช cria seu primeiro arquivo Scala.

Passo 12) Clique com o botรฃo direito do mouse em src para abrir um menu e criar um novo arquivo Scala.

Crie um novo arquivo Scala

Escolha um nome para o arquivo. Para este tutorial de Scala, use OlรกEm seguida, selecione "Objeto" no menu suspenso para o tipo de conteรบdo do arquivo Scala.

Selecione o tipo de objeto

Feito isso, vocรช terรก um arquivo Scala que contรฉm um objeto singleton que vocรช usarรก para executar o cรณdigo.

Objeto singleton criado

Agora que vocรช tem um arquivo Scala com um objeto Hello, escreva seu primeiro programa estendendo o objeto que vocรช criou usando a palavra-chave App.

Estender o objeto com `App` informa ao compilador qual cรณdigo executar quando o programa for iniciado. Imediatamente apรณs estender `App`, uma seta verde aparece no lado esquerdo, indicando que o programa agora estรก pronto para ser executado.

Executar seta no IntelliJ

Executar opรงรฃo Olรก

Dentro do objeto Hello, escreva a funรงรฃo println() para imprimir o texto no console. Execute o programa clicando na seta verde.

Clicar na seta apresenta a opรงรฃo Executar Olรก. Selecionando-a, o cรณdigo รฉ compilado e, apรณs alguns segundos, a saรญda do programa aparece no console do IntelliJ.

Saรญda "Olรก Mundo" no console

Vocรช instalou o Scala com sucesso e agora pode executar seu primeiro programa.

O que vocรช pode fazer com Scala

Scala รฉ amplamente utilizado em diversos domรญnios devido ร  sua flexibilidade e interoperabilidade com a JVM. Casos de uso comuns incluem:

  • Desenvolvimento web front-end com ScalaJS.
  • Desenvolvimento mรณvel para Android e iOS com Scala Native.
  • Bibliotecas do lado do servidor, como HTTP4S, Akka-Http e o Play Framework.
  • Aplicaรงรตes da Internet das Coisas (IoT).
  • Desenvolvimento de jogos.
  • Processamento de linguagem natural usando o conjunto de bibliotecas ScalaNLP.
  • Praticar tรฉcnicas avanรงadas como programaรงรฃo funcional e programaรงรฃo orientada a objetos em conjunto.
  • Aplicaรงรตes de comunicaรงรฃo altamente concorrentes usando atores, uma biblioteca para a JVM inspirada em Erlang.
  • Aprendizado de mรกquina com bibliotecas como Figaro para programaรงรฃo probabilรญstica e Apache Spark para processamento de dados em larga escala.

Funรงรตes anรดnimas

A linguagem Scala suporta funรงรตes anรดnimas, tambรฉm chamadas de funรงรตes anรดnimas. literais de funรงรฃoComo Scala รฉ uma linguagem funcional, os desenvolvedores frequentemente dividem grandes problemas em muitas tarefas pequenas e criam muitas funรงรตes. Para facilitar isso, Scala permite que as funรงรตes sejam instanciado sem nomeVocรช pode atribuรญ-los diretamente a variรกveis โ€‹โ€‹ou a definiรงรตes usando def, conforme mostrado no seguinte exemplo em Scala:

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

Vocรช pode entรฃo usรก-las como funรงรตes regulares, passando parรขmetros:

multiplyByTwo(3)
//6

multiplyByThree(4)
//12

Esses mรฉtodos sรฃo รบteis quando vocรช deseja um cรณdigo limpo e conciso. Funรงรตes anรดnimas sรฃo รบteis para definir mรฉtodos pequenos que nรฃo exigem muito cรณdigo em seu corpo. Elas sรฃo muito simples e nรฃo precisam de nenhuma formalidade para serem criadas.

Esses mรฉtodos nรฃo se limitam a funรงรตes com argumentos e podem ser usados โ€‹โ€‹para instanciar mรฉtodos que nรฃo recebem argumentos.

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

A maioria dessas funรงรตes anรดnimas รฉ usada em outras partes do cรณdigo onde vocรช precisa de uma funรงรฃo rรกpida e eficiente. Por esse motivo, elas tambรฉm sรฃo chamadas de... funรงรตes inlineO uso de funรงรตes anรดnimas รฉ um padrรฃo comum que aparece em toda a biblioteca de coleรงรตes para executar aรงรตes rรกpidas em uma coleรงรฃo.

Por exemplo, o mรฉtodo filter recebe uma funรงรฃo inline para criar outra coleรงรฃo contendo apenas os elementos que atendem aos critรฉrios definidos na funรงรฃo 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)

Aqui, as funรงรตes anรดnimas verificam se o valor da lista รฉ par ou รญmpar e retornam o item correspondente.

//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

Em Scala, tambรฉm รฉ possรญvel usar curingas quando o parรขmetro da funรงรฃo anรดnima nรฃo possui um nome. Por exemplo:

var timesTwo = (_:Int) * 2

timesTwo(5)
//10

Nesse cenรกrio, vocรช nรฃo nomeia o parรขmetro. O sublinhado รฉ usado para representรก-lo.

Avaliaรงรฃo Preguiรงosa

A maioria das linguagens avalia variรกveis โ€‹โ€‹e parรขmetros de funรงรฃo sequencialmente, um apรณs o outro. Em Scala, a palavra-chave lazy Ajuda a lidar com valores que vocรช nรฃo deseja avaliar atรฉ que sejam referenciados.

Uma variรกvel marcada como preguiรงosa nรฃo รฉ avaliada no local onde รฉ definida, o que รฉ comumente conhecido como avaliaรงรฃo imediata. Ela sรณ รฉ avaliada quando รฉ referenciada posteriormente no cรณdigo.

Isso pode ser รบtil quando avaliar um valor envolveria um cรกlculo dispendioso. Se o valor nรฃo for sempre necessรกrio, vocรช evita executar um cรกlculo custoso que pode tornar o software mais lento, tornando a variรกvel preguiรงosa.

lazy val myExpensiveValue = expensiveComputation

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

Este nรฃo รฉ o รบnico caso de uso para variรกveis โ€‹โ€‹preguiรงosas. Elas tambรฉm ajudam a lidar com dependรชncias circulares no cรณdigo.

Se a opรงรฃo de configuraรงรฃo estiver definida como falsa, vocรช nรฃo precisa usar `myExpensiveValue`, o que evita cรกlculos dispendiosos. Isso garante uma experiรชncia mais fluida para os usuรกrios, pois os recursos nรฃo sรฃo desperdiรงados com valores que nunca sรฃo lidos.

A abordagem lazy tambรฉm รฉ รบtil com argumentos de funรงรฃo, onde os argumentos sรฃo usados โ€‹โ€‹apenas quando sรฃo referenciados dentro da funรงรฃo. Esse conceito รฉ chamado de parรขmetros de chamada por nome.

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

Muitas linguagens utilizam a abordagem de chamada por valor para avaliar argumentos. Um parรขmetro passado por nome sรณ รฉ avaliado quando necessรกrio dentro do corpo da funรงรฃo. Uma vez avaliado, o valor รฉ armazenado e pode ser reutilizado posteriormente sem necessidade de reavaliaรงรฃo, um conceito conhecido como memoizaรงรฃo.

Inferรชncia de tipo

Em Scala, vocรช nรฃo precisa declarar tipos para cada variรกvel que cria, pois o compilador Scala pode inferir os tipos a partir do lado direito de uma expressรฃo. Isso permite que seu cรณdigo seja mais conciso e evita que vocรช escreva cรณdigo repetitivo onde o tipo esperado รฉ รณbvio.

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

Funรงรฃo de ordem superior

Uma funรงรฃo de ordem superior รฉ uma funรงรฃo que pode receber outras funรงรตes como argumentos e retornar uma funรงรฃo como tipo de retorno. Em Scala, as funรงรตes sรฃo consideradas cidadรฃs de primeira classe. Usar funรงรตes dessa forma permite grande flexibilidade nos tipos de programas que vocรช pode construir. Vocรช pode criar funรงรตes dinamicamente e passar funcionalidades dinamicamente para outras funรงรตes.

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

Na funรงรฃo acima, vocรช passa um Int e uma funรงรฃo que recebe um Int e retorna um IntVocรช pode passar qualquer funรงรฃo com essa assinatura. Por assinatura, queremos dizer a entrada e a saรญda de uma funรงรฃo. Uma assinatura de Int => Int Significa que uma funรงรฃo recebe um Int como entrada e retorna um Int como saรญda.

Uma assinatura de () => Int Significa que uma funรงรฃo nรฃo recebe nada como entrada e retorna um inteiro como saรญda. Um exemplo de tal funรงรฃo รฉ uma que gera um inteiro aleatรณrio.

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

A funรงรฃo acima possui uma assinatura () => Int.

Uma funรงรฃo tambรฉm pode ter uma assinatura. () => UnitIsso significa que a funรงรฃo nรฃo recebe nada como parรขmetro e nรฃo retorna nenhum tipo. Em vez disso, a funรงรฃo pode alterar algum estado ou executar uma aรงรฃo predeterminada.

Esses tipos de mรฉtodos nรฃo sรฃo recomendados porque podem funcionar como uma caixa preta, afetando o sistema de maneiras desconhecidas. Alรฉm disso, sรฃo mais difรญceis de testar. Ter tipos de entrada e saรญda explรญcitos permite que vocรช entenda o que sua funรงรฃo faz.

Uma funรงรฃo de ordem superior tambรฉm pode retornar uma funรงรฃo. Por exemplo, vocรช poderia criar um mรฉtodo que retorna uma funรงรฃo de potenciaรงรฃo, que recebe um nรบmero e aplica um valor a ele.

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

A funรงรฃo acima recebe um Int. Seu tipo de retorno รฉ uma funรงรฃo anรดnima que recebe um Int. x e a utiliza como argumento para a funรงรฃo potรชncia.

Escovando

Em Scala, vocรช pode converter uma funรงรฃo que recebe dois argumentos em uma que recebe um argumento por vez. Ao passar um argumento, vocรช o aplica parcialmente e obtรฉm uma funรงรฃo que recebe o argumento restante para completar a chamada. O currying permite construir funรงรตes adicionando argumentos parcialmente.

Isso รฉ รบtil para criar funรงรตes dinamicamente antes de se ter um conjunto completo de argumentos.

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

Se vocรช precisa de uma funรงรฃo que multiplique por um nรบmero especรญfico, nรฃo precisa criar outro mรฉtodo de multiplicaรงรฃo. Vocรช pode aplicar um argumento ร  funรงรฃo curried e reutilizar o resultado:

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

var multiplyByFive = multiplyTwoNumbers(5) _

multiplyByFive(4)

//returns 20

Correspondรชncia de padrรตes

Scala possui um mecanismo integrado poderoso que ajuda a verificar se uma variรกvel corresponde a determinados critรฉrios, de forma semelhante a uma instruรงรฃo switch em Python. Java ou uma cadeia de instruรงรตes if/else. A linguagem suporta casamento de padrรตes, que vocรช pode usar para verificar se uma variรกvel รฉ de um tipo especรญfico. O casamento de padrรตes em Scala รฉ poderoso e pode desestruturar componentes que possuem um unapply Mรฉtodo para obter os campos que lhe interessam diretamente da variรกvel que estรก sendo comparada.

O casamento de padrรตes em Scala tambรฉm oferece uma sintaxe mais agradรกvel do que uma instruรงรฃo switch.

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

Vocรช compara a variรกvel a um conjunto de opรงรตes. Quando a variรกvel atende aos critรฉrios, a expressรฃo ร  direita da seta grossa (=>) รฉ avaliada e retorna o resultado da correspondรชncia.

O sublinhado captura casos que nรฃo sรฃo correspondidos no cรณdigo, espelhando o comportamento do caso padrรฃo em uma instruรงรฃo 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
}

No cรณdigo acima, vocรช pode detectar o tipo do myItem variรกvel e, com base nisso, ramificar para um cรณdigo especรญfico.

A correspondรชncia de padrรตes verifica se a variรกvel corresponde a cada caso em ordem.

O sublinhado funciona como um marcador que corresponde a qualquer condiรงรฃo que as outras instruรงรตes `case` nรฃo abranjam. Vocรช pega uma variรกvel myItem e ligue para o match mรฉtodo.

  • Verifique se myItem is true e execute a lรณgica no lado direito da seta grossa โ€œ=>โ€.
  • Use o sublinhado para indicar qualquer coisa que nรฃo corresponda a nenhuma das instruรงรตes `case` definidas no cรณdigo.

Com classes de caso, vocรช pode desestruturar a classe para extraccampos t dentro do objeto.

Ao utilizar a blockchain da sealed Ao usar a palavra-chave para definir classes, vocรช obtรฉm o benefรญcio de ter o compilador verificando exaustivamente os casos que vocรช tenta corresponder e avisando se vocรช esquecer de tratar algum deles.

Imutabilidade

ร‰ possรญvel criar valores que nรฃo podem ser alterados por outras funรงรตes em Scala usando o val palavra-chave. Isso รฉ alcanรงado em Java usando o final palavra-chave. Em Scala, vocรช usa um val ao criar uma variรกvel em vez de var, que รฉ a alternativa para variรกveis โ€‹โ€‹mutรกveis.

Uma variรกvel definida usando o val A palavra-chave รฉ somente leitura, enquanto uma definida com var Pode ser lido e alterado posteriormente por outras funรงรตes ou pelo usuรกrio no 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

Tentando atribuir um valor a myNumber apรณs declarรก-lo como um val gera um erro de tempo de compilaรงรฃo: โ€œreatribuiรงรฃo para valโ€.

Por que usar Imutabilidade?

A imutabilidade ajuda a impedir que o cรณdigo e outros programadores alterem valores inesperadamente, o que levaria a resultados imprevisรญveis. Se os usuรกrios de um valor precisarem alterรก-lo, podem simplesmente fazer uma cรณpia. Dessa forma, evitam-se erros causados โ€‹โ€‹por mรบltiplos agentes alterando a mesma variรกvel.

Classes e Objetos

Objetos sรฃo entidades do mundo real, e uma classe รฉ um modelo que define objetos. Classes possuem estado e comportamentos. Os estados sรฃo valores ou variรกveis. Os comportamentos sรฃo os mรฉtodos em Scala.

A prรณxima seรงรฃo mostra como definir uma classe, instanciรก-la e usรก-la em Scala.

Aqui estรก uma classe chamada Retรขngulo que possui dois valores e duas funรงรตes. Vocรช tambรฉm pode usar os parรขmetros. l e b diretamente como campos no programa. Vocรช tem um objeto que possui um mรฉtodo principal e instancia a classe com dois valores.

Exemplo:

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)
  }
}

Em Scala, todos os campos e mรฉtodos sรฃo pรบblicos por padrรฃo. ร‰ essencial usar override Porque toString jรก estรก definido para cada objeto em Scala.

Heranรงa

Scala possui mรบltiplos tipos de heranรงa (simples, multinรญvel, mรบltipla, hierรกrquica e hรญbrida) que compartilham muitas semelhanรงas com as formas tradicionais encontradas em linguagens de programaรงรฃo. JavaVocรช pode herdar tanto de classes quanto de caracterรญsticas. Vocรช herda os membros de uma classe para outra usando a palavra-chave `herdate`. extendsIsso possibilita a reutilizaรงรฃo.

ร‰ possรญvel herdar de uma ou de mรบltiplas classes. Tambรฉm รฉ possรญvel herdar de subclasses que, por sua vez, possuem suas prรณprias superclasses, criando assim uma hierarquia de heranรงa.

No exemplo em Scala abaixo, a classe base รฉ Circlee a classe derivada รฉ SphereUm cรญrculo possui um valor chamado raio, que รฉ herdado na classe Esfera. O mรฉtodo calcArea รฉ substituรญdo usando a palavra-chave override.

Exemplo:

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
    }
  }

Abstracรงรฃo

Em Scala, vocรช pode criar abstracmรฉtodos t e campos de membros usando abstracclasses e caracterรญsticas. Dentro de abstracPara classes e caracterรญsticas, vocรช pode definir abstraccampos t sem implementรก-los.

Exemplo:

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"
    }
}

Esses campos sรฃo implementados pelas classes que estendem o trait ou abs.tracclasse t. Vocรช pode usar caracterรญsticas para criar construรงรตes.tracDefina o que um aplicativo deve fazer e, em seguida, implemente esses mรฉtodos posteriormente.

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

Dessa forma, vocรช pode planejar a aparรชncia de um aplicativo sem implementar os mรฉtodos, ajudaping Vocรช imagina como vรกrios mรฉtodos aparecerรฃo. Isso segue um padrรฃo conhecido como programaรงรฃo para abs.tracรงรตes em vez de ร  implementaรงรฃo real.

Uma aula precedida por abstract A palavra-chave pode conter ambos os abstract e nรฃo-abstracmรฉtodos t. No entanto, a heranรงa mรบltipla nรฃo รฉ suportada em abstracclasses t, entรฃo vocรช sรณ pode estender um abs.tracclasse t.

Objetos Singleton

Um singleton รฉ uma classe que รฉ instanciada apenas uma vez em um programa. Ele vem de um padrรฃo de programaรงรฃo popular e รบtil conhecido como "padrรฃo singleton". ร‰ รบtil para criar instรขncias que devem ter longa duraรงรฃo e serem acessadas com frequรชncia ao longo do programa, onde o estado รฉ essencial para coordenar eventos em um sistema. Criar uma classe desse tipo em Scala รฉ fรกcil porque Scala fornece um meio simples de criar singletons usando o `std::string`. object palavra chave.

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

Vocรช pode entรฃo referenciar esse objeto em todo o programa com a garantia de que todas as partes do programa veem os mesmos dados, pois existe apenas uma instรขncia dele.

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

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

O conceito de membros estรกticos nรฃo existe em Scala, razรฃo pela qual vocรช usa objetos singleton que se comportam como membros estรกticos de uma classe.

Classes implรญcitas

Classes implรญcitas sรฃo um recurso adicionado na versรฃo 2.10 e sรฃo usadas principalmente para adicionar novas funcionalidades a classes fechadas existentes.

As implicit A palavra-chave deve ser definida em uma classe, objeto ou trait. O construtor principal de uma classe implรญcita deve ter exatamente um argumento em sua primeira lista de parรขmetros. Ele tambรฉm pode incluir uma lista de parรขmetros implรญcitos adicionais.

No exemplo em Scala abaixo, foi adicionada uma nova funcionalidade para substituir vogais de uma String por *.

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

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

Vocรช precisa importar a classe implรญcita na classe onde vocรช a estรก utilizando.

import StringUtil.StringEnhancer

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

Programaรงรฃo Orientada a Objetos (POO) vs. Programaรงรฃo Funcional (PF)

Em POO, os programas sรฃo construรญdos por grupos.ping Os dados e as funรงรตes que operam sobre esses dados sรฃo agrupados em unidades altamente conectadas. Os objetos carregam seus dados em campos e os mรฉtodos operam sobre eles. Nesse estilo de programaรงรฃo, a principal abstraรงรฃotracA essรชncia estรก nos dados, pois os mรฉtodos criados tรชm como objetivo operar sobre eles.

Programaรงรฃo funcionalPor outro lado, separa os dados das funรงรตes que operam sobre eles. Isso permite que os desenvolvedores tratem as funรงรตes como o absoluto.tracรงรฃo e forรงa motriz na modelagem de programas.

Scala possibilita a programaรงรฃo funcional ao tratar funรงรตes como cidadรฃs de primeira classe, permitindo que sejam passadas como valores para outras funรงรตes e retornadas como valores tambรฉm. A combinaรงรฃo desses dois paradigmas tornou Scala uma รณtima escolha para a construรงรฃo de softwares complexos em setores como o de ciรชncia de dados.

Frameworks importantes no Scala

Aqui estรฃo alguns frameworks importantes para Scala:

  • Jogar รฉ uma estrutura de aplicativo da web de cรณdigo aberto que usa Arquitetura MVCLanรงado em 2007 e agora licenciado sob a Apache, tornou-se um dos frameworks mais populares no GitHub em 2013. Empresas como o LinkedIn, WalmartSamsung e Eero usam essa estrutura.
  • Levantar รฉ outro framework web gratuito escrito em Scala, lanรงado em 2007. O Foursquare utiliza o framework Lift. ร‰ um framework de alto desempenho e rรกpido para desenvolvimento.
  • Como Fornece um conjunto de ferramentas para construir aplicaรงรตes orientadas a mensagens altamente concorrentes, distribuรญdas e resilientes na JVM.
  • Gatos - Leecork รฉ uma biblioteca que fornece abstracรงรตes para programaรงรฃo funcional.
  • Spark ร‰ um mecanismo de anรกlise unificado para processamento de dados em larga escala, amplamente utilizado em fluxos de trabalho de big data e aprendizado de mรกquina.

Suporte de simultaneidade

  • Em Scala, os valores sรฃo imutรกveis โ€‹โ€‹por padrรฃo, o que torna a linguagem muito adaptรกvel a ambientes concorrentes.
  • Scala possui muitas caracterรญsticas que a tornam ideal para aplicaรงรตes concorrentes.
  • Futuros e Promessas facilitam o processamento de dados de forma assรญncrona, apoiando assim o paralelismo.
  • Akka รฉ um conjunto de ferramentas que utiliza o modelo de concorrรชncia de atores. Os atores agem quando recebem mensagens.
  • Simultaneidade usando threads de Java Tambรฉm รฉ compatรญvel com Scala.
  • O processamento de fluxos de dados รฉ outro excelente recurso que permite o processamento contรญnuo e em tempo real dos dados.

Scala tem algumas das melhores bibliotecas de simultaneidade do Java ecossistema:

  • Nativo Java tรณpicos.
  • Fibras de bibliotecas como o Vertx.
  • ZIO รฉ uma biblioteca que possui primitivas para auxiliar no tratamento de concorrรชncia e computaรงรฃo assรญncrona.
  • Memรณria transacional de software (STM) para transaรงรตes.
  • Futuro, que jรก estรก integrado ร  linguagem Scala.

Java vs.

Aqui estรฃo os principais diferenรงas entre Java e escala.

Scala Java
Mais compacto e conciso. Blocos de cรณdigo comparativamente maiores.
Projetado e desenvolvido para ser tanto orientado a objetos quanto funcional. Suporta uma ampla variedade de recursos de programaรงรฃo funcional, como concorrรชncia e imutabilidade. Originalmente desenvolvida como uma linguagem orientada a objetos, passou a suportar recursos de programaรงรฃo funcional em versรตes recentes. Ainda assim, nรฃo รฉ tรฃo robusta quanto Scala para programaรงรฃo funcional.
Utiliza o modelo de atores para suportar a concorrรชncia. Usa o modelo convencional baseado em thread para simultaneidade.
Compatรญvel com frameworks como Play e Lift. Compatรญvel com Spring, Grails e muitos outros.
Suporta avaliaรงรฃo preguiรงosa. Nรฃo oferece suporte nativo ร  avaliaรงรฃo preguiรงosa.
Nรฃo hรก membros estรกticos. Contรฉm membros estรกticos.
Suporta sobrecarga do operador. Nรฃo suporta sobrecarga de operadores.
A compilaรงรฃo do cรณdigo-fonte รฉ comparativamente lenta. A compilaรงรฃo do cรณdigo-fonte รฉ mais rรกpida do que em Scala.
Os traรงos agem como Java 8 interfaces. Java 8. As interfaces tentam preencher a lacuna entre classes e interfaces.
ร€s vezes, รฉ necessรกrio reescrever o cรณdigo ao atualizar versรตes. Geralmente nรฃo รฉ necessรกrio reescrever o cรณdigo entre versรตes.
A seguranรงa de tipos proporciona alta confiabilidade ao cรณdigo, mas nรฃo garante ausรชncia absoluta de erros. Tipo estรกtico forteping Ajuda a reduzir muitos defeitos em tempo de execuรงรฃo.
Possui algumas limitaรงรตes de compatibilidade com versรตes anteriores entre as versรตes principais. Forte compatibilidade retroativa a longo prazo.
OperaOs operadores sรฃo tratados como chamadas de mรฉtodo. OperaOs "tors" sรฃo uma sintaxe especial e nรฃo sรฃo chamadas de mรฉtodo.
Suporta heranรงa mรบltipla usando caracterรญsticas. Nรฃo suporta heranรงa mรบltipla usando classes; em vez disso, utiliza interfaces.
Code Estรก escrito de forma concisa. Code estรก escrito de forma mais prolixa.
Scala nรฃo contรฉm a palavra-chave estรกtica. Java contรฉm a palavra-chave estรกtica.

Perguntas Frequentes

Scala tem uma curva de aprendizado mais acentuada do que Java porque combina estilos orientados a objetos e funcionais. No entanto, desenvolvedores com Java Com a experiรชncia, geralmente se aprende o bรกsico rapidamente. Praticar com projetos pequenos e o Scala REPL acelera o aprendizado.

Sim. O Scala continua a impulsionar sistemas de grande escala em empresas que utilizam Akka. Sparke Kafka. A demanda continua forte em engenharia de dados, fintech e sistemas distribuรญdos, onde o desempenho da JVM e a programaรงรฃo funcional sรฃo valiosos.

Sim. Os assistentes de programaรงรฃo de IA modernos entendem a sintaxe Scala, o sistema de tipos e frameworks como Akka e... SparkEles ajudam a gerar cรณdigo repetitivo, sugerem padrรตes funcionais, explicam erros de compilaรงรฃo e refatoram o cรณdigo, acelerando o desenvolvimento tanto para iniciantes quanto para especialistas.

Scala impulsiona o Apache SparkScala รฉ o principal mecanismo para processamento de dados em larga escala em pipelines de IA. Bibliotecas como Breeze, Smile e Figaro oferecem suporte ร  computaรงรฃo numรฉrica, aprendizado de mรกquina e modelagem probabilรญstica, tornando Scala uma excelente opรงรฃo para ciรชncia de dados em produรงรฃo.

Um `val` cria uma associaรงรฃo imutรกvel que รฉ avaliada imediatamente. Um `var` cria uma associaรงรฃo mutรกvel que pode ser reatribuรญda. Um `val` preguiรงoso adia a avaliaรงรฃo atรฉ que o valor seja acessado pela primeira vez e, em seguida, armazena o resultado em cache para leituras subsequentes.

Resuma esta postagem com: