Tutorial Scala
Resumo do tutorial Scala
Este tutorial do scala cobre todos os aspectos e tรณpicos do scala. Vocรช aprenderรก todos os fundamentos do zero, como o que รฉ scala, o processo de instalaรงรฃo do scala, programas Scala, funรงรตes Scala, avaliaรงรฃo preguiรงosa, interface de tipo, classes e objetos, heranรงa, abstraรงรตes, Java e diferenรงas de escala, etc.
O que รฉ Escala?
Scala รฉ uma linguagem de programaรงรฃo estaticamente tipada que incorpora programaรงรฃo funcional e orientada a objetos para aumentar a escalabilidade dos aplicativos. Scala roda principalmente em plataforma JVM e tambรฉm pode ser usado para escrever software para plataformas nativas usando Scala-Native e JavaScript tempos de execuรงรฃo por meio de ScalaJs.
Scala รฉ uma linguagem escalรกvel usada para escrever software para mรบltiplas plataformas. Por isso recebeu o nome de โScalaโ. Esta linguagem destina-se a resolver os problemas de Java enquanto simultaneamente รฉ mais conciso. Inicialmente projetado por Martin Odersky, foi lanรงado em 2003.
Por que aprender Scala
Aqui estรฃo as principais razรตes para aprender a linguagem de programaรงรฃo Scala:
- Scala รฉ fรกcil de aprender para programadores orientados a objetos, Java desenvolvedores. Estรก se tornando uma das lรญnguas populares nos รบltimos anos.
- Scala oferece funรงรตes de primeira classe para usuรกrios
- Scala pode ser executado em JVM, abrindo caminho para a interoperabilidade com outras linguagens.
- Ele foi projetado para aplicativos simultรขneos, distribuรญdos e resilientes orientados por mensagens. ร uma das lรญnguas mais exigentes desta dรฉcada.
- ร uma linguagem concisa, poderosa e pode crescer rapidamente de acordo com a demanda de seus usuรกrios.
- ร orientado a objetos e possui muitos recursos de programaรงรฃo funcional, proporcionando muita flexibilidade para os desenvolvedores codificarem da maneira que desejarem.
- Scala oferece muitos tipos de pato
- Tem menos clichรช se vocรช vem de Java
- Os frameworks Lift and Play escritos em Scala estรฃo em curva de crescimento.
Como instalar Scala
Para comeรงar a escrever programas Scala, vocรช precisa instalรก-lo em seu computador. Para fazer isso, vocรช precisarรก visitar o site deles https://www.scala-lang.org/download/ para baixar a versรฃo mais recente do Scala.
Seguindo o link, somos levados a duas opรงรตes que podemos escolher para instalar o Scala em nossas mรกquinas. Para este tutorial do Scala, faremos o download do IntelliJ IDEA.
Depois de visitar o link de download, vocรช encontrarรก duas versรตes do IntelliJ IDE.
Para este tutorial do Scala, baixaremos a Community Edition, que รฉ gratuita e vem com tudo que vocรช precisa para escrever programas Scala.
Passo 1) Selecione a ediรงรฃo da comunidade
Na pรกgina, clique no menu suspenso Community Edition.
Ele nos apresenta a opรงรฃo de baixar o IDE IntelliJ junto com o JBR que contรฉm uma implementaรงรฃo JDK(Java Development Kit) OpenJDK que Scala precisa para compilar e executar o cรณdigo.
Passo 2) Execute a instalaรงรฃo
Depois de baixar o IntelliJ, clique duas vezes nele para executar o assistente de instalaรงรฃo e siga a caixa de diรกlogo.
Passo 3) Selecione um local
Escolha um local para instalar o IDE.
Se por acaso vocรช nรฃo baixou aquele com o JDK, ainda receberemos um prompt onde podemos verificar para baixรก-lo marcando a caixa de seleรงรฃo.
Passo 4) Clique em prรณximo
Deixe os outros padrรตes como estรฃo e clique em Avanรงar.
Passo 5) Clique no รญcone de inicializaรงรฃo
Assim que a instalaรงรฃo for concluรญda, execute o IDE IntelliJ clicando em seu รญcone de inicializaรงรฃo no menu de inicializaรงรฃo como um aplicativo normal.
Vocรช ainda precisa passar por uma etapa adicional para adicionar o plugin Scala ao IntelliJ; vocรช faz isso clicando no menu suspenso no menu de configuraรงรฃo localizado na parte inferior direita da tela e selecionando a opรงรฃo de plugin.
Na aba Marketplace, uma busca por Scala apresentarรก o plugin como o primeiro resultado na tag Languages.
Passo 6) Instalar plugin
Clique em instalar, que iniciarรก o download do plugin.
Passo 7) Reinicie o IDE
Apรณs a conclusรฃo do download, vocรช serรก solicitado a reiniciar o IDE para que o plugin instalado possa comeรงar a funcionar.
Depois de reiniciar, vocรช estarรก na mesma pรกgina de quando executamos o IDE, mas desta vez jรก instalamos o plugin Scala.
Programa Scala Olรก Mundo
Passo 1) Selecione a opรงรฃo Criar Projeto, que nos levarรก a uma pรกgina onde podemos selecionar o tipo de linguagem que nosso projeto utilizarรก.
Passo 2) escolha Scala marcando a caixa de seleรงรฃo Scala e clique em prรณximo.
Passo 3) Selecione um local para salvar nosso arquivo de projetos e dรช um nome ao nosso projeto.
Se o diretรณrio nรฃo existir, o IntelliJ solicitarรก permissรฃo para criar a pasta. Aceite e clique em Concluir. Vocรช serรก levado ao seu projeto Scala, que atualmente nรฃo possui nenhum cรณdigo Scala.
Levarรก algum tempo para carregar alguns รญndices, entรฃo nรฃo se preocupe se vocรช nรฃo conseguir fazer nada imediatamente enquanto houver uma barra de progresso na parte inferior do seu IDE, significa simplesmente que seu IDE estรก carregando alguns arquivos necessรกrios para executar o Scala e ajuda com o preenchimento automรกtico do IDE.
Passo 4) A seguir, clicaremos na aba de projetos ร esquerda do IDE e expandiremos para podermos ver o conteรบdo do nosso projeto.
No momento o projeto estรก vazio e contรฉm apenas uma pasta .idea e um arquivo hello-world.iml gerado pelo IDE. Nosso ponto de interesse รฉ a pasta src. Src รฉ onde armazenamos o cรณdigo fonte do nosso projeto. ร onde criaremos nosso primeiro arquivo Scala.
Passo 5) Clique com o botรฃo direito em src para abrir um menu para criar um novo arquivo Scala.
Criaremos entรฃo um nome para o arquivo, neste tutorial do Scala usaremos hello e depois escolheremos em um menu suspenso o que colocar como conteรบdo do arquivo Scala. Selecione โObjetoโ
Feito isso, teremos um arquivo Scala que possui um objeto Singleton que usaremos para executar nosso cรณdigo.
Agora que vocรช tem um arquivo Scala com um objeto Hello. Vocรช escreverรก seu primeiro programa estendendo o objeto criado usando a palavra-chave App.
Estender nosso objeto com App informa ao compilador qual cรณdigo executar quando iniciar seu programa. Imediatamente apรณs estender o App, uma seta verde aparece no lado esquerdo, indicando que agora vocรช pode executar seu programa.
Dentro do objeto Hello, escrevemos uma funรงรฃo println() que รฉ usada para imprimir o texto dentro dele no console. Executaremos nosso cรณdigo clicando na seta verde.
Clicar na seta nos apresenta a opรงรฃo Executar, olรก, ao clicar nela nosso cรณdigo comeรงarรก a ser compilado e apรณs alguns segundos veremos os resultados do nosso programa impressos no console que estรก embutido no IDE IntelliJ.
E pronto, instalamos o Scala com sucesso e executamos nosso primeiro programa.
O que vocรช pode fazer com Scala
- Desenvolvimento web front-end com ScalaJS
- Desenvolvimento mรณvel, ambos Android Desenvolvimento e IOS โ com Scala Native
- Bibliotecas do lado do servidor como HTTP4S, Akka-Http, Play Framework
- Internet das coisas usando
- Desenvolvimento de jogos
- PNL โ Processamento de Linguagem Natural usando um conjunto de bibliotecas ScalaNLP
- Testando tรฉcnicas avanรงadas de programaรงรฃo, como Programaรงรฃo Funcional e Programaรงรฃo Orientada a Objetos
- Construa um aplicativo de comunicaรงรฃo altamente concorrente usando atores de uma biblioteca para JVM inspirada em Erlang
- Use-o para aprendizado de mรกquina usando bibliotecas como Figaro, que faz programaรงรฃo probabilรญstica, e Apache Spark que.
Funรงรตes anรดnimas
A linguagem Scala possui funรงรตes anรดnimas, que tambรฉm sรฃo chamadas literais de funรงรฃo. Sendo Scala uma linguagem funcional, muitas vezes significa que os desenvolvedores dividem grandes problemas em muitas tarefas pequenas e criam muitas funรงรตes para resolver esses problemas. Para facilitar a criaรงรฃo de funรงรตes, Scala contรฉm essas funรงรตes que podem ser instanciado sem nome. Podemos atribuรญ-los diretamente a variรกveis โโโโou definiรงรตes 'def' conforme mostrado no exemplo de Scala abaixo:
val multiplyByTwo = (n:Int) => n * 2 def multiplyByThree = (n:Int) => n *3
Podemos entรฃo usar a maneira normal como usamos funรงรตes, passando parรขmetros para elas a seguir.
multiplyByTwo(3) //6 multiplyByThree(4) //12
Esses mรฉtodos sรฃo รบteis quando queremos um cรณdigo limpo e conciso. Podemos usar funรงรตes anรดnimas ao definir mรฉtodos que nรฃo sejam grandes e nรฃo exijam muito cรณdigo em seu corpo. Eles sรฃo muito simples e nรฃo precisam de cerimรดnia para serem criados.
Esses mรฉtodos nรฃo estรฃo limitados a funรงรตes com argumentos e podem ser usados โโpara instanciar mรฉtodos que nรฃo aceitam nenhum argumento.
val sayHello = ()=>{ println("hello") }
A maioria dessas funรงรตes anรดnimas sรฃo usadas em outras partes do nosso cรณdigo onde precisamos criar uma funรงรฃo rรกpida.
Outra razรฃo pela qual essas funรงรตes tambรฉm sรฃo chamadas de funรงรตes inline. O uso de funรงรตes anรดnimas รฉ um padrรฃo comum usado amplamente na biblioteca de coleรงรตes para executar aรงรตes rรกpidas em uma coleรงรฃo.
Por exemplo, temos o mรฉtodo filter que usa uma funรงรฃo inline/funรงรฃo anรดnima para criar outra coleรงรฃo apenas com elementos que atendam aos critรฉrios que definimos 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 os mรฉtodos que temos como funรงรตes anรดnimas sรฃo aqueles que verificam se o valor que obtemos da lista รฉ รญmpar e par e retornam o item.
//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
No Scala, tambรฉm รฉ possรญvel usar curingas onde os parรขmetros da nossa funรงรฃo anรดnima nรฃo sรฃo nomeados. Por exemplo
var timesTwo = (_:Int)*2 timesTwo(5) //10
Neste cenรกrio, nรฃo nomeamos o parรขmetro que estamos passando. A รบnica coisa que usamos รฉ um sublinhado 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. No Scala, temos uma palavra-chave chamada preguiรงoso, que ajuda a lidar com valores que nรฃo queremos que sejam avaliados atรฉ que sejam referenciados.
Uma variรกvel marcada como preguiรงosa nรฃo serรก avaliada onde for definida, o que รฉ comumente conhecido como avaliaรงรฃo antecipada, ela sรณ serรก avaliada quando for referenciada posteriormente no cรณdigo.
Isso pode ser รบtil quando avaliar um valor pode ser um cรกlculo caro; se o valor nรฃo for sempre necessรกrio, podemos evitar a execuรงรฃo de um cรกlculo caro que pode tornar nosso software lento, tornando nossa 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. Eles tambรฉm ajudam a lidar com questรตes de dependรชncia circular no cรณdigo.
Caso as configuraรงรตes sejam falsas, talvez nรฃo precisemos usar myExpensiveValue, o que pode nos levar a evitar cรกlculos caros, o que ajuda a garantir que os usuรกrios se divirtam usando nosso aplicativo, pois nossas outras necessidades podem ser computadas adequadamente sem sobrecarregar o carneiro.
Caso as configuraรงรตes sejam falsas, talvez nรฃo precisemos usar myExpensiveValue, o que pode nos levar a evitar cรกlculos caros, o que ajuda a garantir que os usuรกrios se divirtam usando nosso aplicativo, pois nossas outras necessidades podem ser computadas adequadamente sem sobrecarregar o carneiro.
A preguiรงa tambรฉm ajuda com argumentos de funรงรฃo, onde os argumentos sรณ sรฃo usados โโquando sรฃo referenciados dentro da funรงรฃo. Este 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 usam a forma de chamada por valor para avaliar argumentos. O parรขmetro passado atravรฉs da chamada por nome sรณ serรก avaliado quando necessรกrio no corpo da funรงรฃo e nรฃo serรก avaliado antes disso. Uma vez avaliado o valor, ele รฉ armazenado e pode ser reutilizado posteriormente sem que seja necessรกrio reavaliรก-lo. Um conceito conhecido como memoizaรงรฃo.
Inferรชncia de tipo
No Scala, vocรช nรฃo precisa declarar tipos para cada variรกvel criada. Isso ocorre porque o compilador Scala pode fazer inferรชncia de tipos com base na avaliaรงรฃo do lado direito. Isso permite que seu cรณdigo seja mais conciso โ nos livra de escrever clichรชs onde o tipo esperado รฉ รณbvio
var first:String = "Hello, " var second:String = "World" var third = first + second //the compile infers that third is of type String
Funรงรฃo de ordem superior
Uma funรงรฃo de ordem superior รฉ uma funรงรฃo que pode receber funรงรตes como argumentos e retornar uma funรงรฃo como tipo de retorno. No Scala, as funรงรตes sรฃo consideradas cidadรฃs de primeira classe. Usar estas funรงรตes desta forma permite-nos ser muito flexรญveis no tipo de programas que podemos fazer. Podemos criar funรงรตes dinamicamente e alimentar funcionalidades dinamicamente para outras funรงรตes.
def doMathToInt(n:Int, myMathFunction:Int=>Int): Int ={
myMathFunction(n)
}
Na funรงรฃo acima, passamos um int e uma funรงรฃo que recebe um int e retorna um int. Podemos passar qualquer funรงรฃo dessa 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 Int como saรญda. Um exemplo de funรงรฃo como essa seria aquela que gera um int aleatรณrio para nรณs.
def generateRandomInt()={
return scala.util.Random.nextInt()
}
A funรงรฃo acima possui uma assinatura ()=>Int
Podemos ter uma funรงรฃo que possui uma assinatura scala()=>Unit. Isso significa que as funรงรตes nรฃo recebem nada e nรฃo retornam um tipo. A funรงรฃo poderia estar fazendo algum tipo de cรกlculo, alterando algo para fazer algo predeterminado.
Porรฉm, esses tipos de mรฉtodos nรฃo sรฃo incentivados, pois parecem ser uma caixa preta que pode afetar um sistema de maneiras desconhecidas. Eles tambรฉm nรฃo sรฃo testรกveis. Ter tipos de entrada e saรญda explรญcitos nos permite raciocinar sobre o que nossa funรงรฃo faz.
Uma funรงรฃo de ordem superior tambรฉm pode retornar uma funรงรฃo.
Por exemplo, poderรญamos criar um mรฉtodo que criaria uma funรงรฃo de potรชncia, ou seja, pegaria um nรบmero e aplicaria potรชncia a ele.
def powerByFunction(n:Int):Int=>Int = {
return (x:Int)=> scala.math.pow(x,n).toInt
}
A funรงรฃo acima recebe um int. Nosso tipo de retorno รฉ uma funรงรฃo anรดnima que recebe um Int x, * usamos o int x como argumento para a funรงรฃo de potรชncia.
Escovando
No Scala, podemos converter uma funรงรฃo que recebe dois argumentos em uma que recebe um argumento por vez. Quando passamos um argumento, nรณs o aplicamos parcialmente e terminamos com uma funรงรฃo que leva um argumento para completar a funรงรฃo. Currying nos permite criar funรงรตes adicionando parcialmente alguns argumentos.
Isto pode ser รบtil para criar funรงรตes dinamicamente antes de termos um conjunto completo de argumentos
def multiply two numbers(n:Int)(m:Int): Unit ={
return n * m
}
Se precisarmos criar uma funรงรฃo que multiplique por algum nรบmero especรญfico, nรฃo precisamos criar outro mรฉtodo de multiplicaรงรฃo.
Podemos simplesmente chamar .curried em nossa funรงรฃo acima e obter uma funรงรฃo que recebe primeiro um argumento e retorna uma funรงรฃo parcialmente aplicada
def multiplyTwoNumbers(n:Int)(m:Int): Unit ={
return n * m
}
var multiplyByFive = multiplyTwoNumbers(5)
multiplyByFive(4)
//returns 20
Correspondรชncia de padrรตes
Scala possui um poderoso mecanismo embutido para nos ajudar a verificar se uma variรกvel corresponde a determinados critรฉrios, da mesma forma que farรญamos em uma instruรงรฃo switch em Java ou em uma sรฉrie de instruรงรตes if/else. A linguagem possui correspondรชncia de padrรตes que podemos usar para verificar se uma variรกvel รฉ de um tipo especรญfico. A correspondรชncia de padrรตes no Scala รฉ poderosa e pode ser usada para desestruturar os componentes que possuem um mรฉtodo unapply para obter os campos nos quais estamos interessados โโdiretamente da variรกvel que estamos combinando.
A correspondรชncia de padrรตes do Scala tambรฉm fornece uma sintaxe mais agradรกvel em comparaรงรฃo com a instruรงรฃo switch.
myItem match {
case true => //do something
case false => //do something else
case _ => //if none of the above do this by default
}
Comparamos nossa variรกvel a um conjunto de opรงรตes e, quando a variรกvel que estamos combinando atende aos critรฉrios, a expressรฃo no lado direito da seta grossa (=>) รฉ avaliada e retornada como resultado da correspondรชncia.
Usamos um sublinhado para capturar casos que nรฃo correspondem em nosso cรณdigo. Ele reflete o comportamento do caso padrรฃo ao lidar com instruรงรตes 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 _ => //case we have a type we don't recognize do sth else
}
No cรณdigo acima, vocรช pode descobrir o tipo da variรกvel myItem e com base nisso ramificar para algum cรณdigo especรญfico.
A correspondรชncia de padrรตes verifica se a variรกvel corresponde
O sublinhado funciona como um espaรงo reservado que corresponde a qualquer outra condiรงรฃo que nรฃo corresponda aos outros itens nas instruรงรตes case acima. Pegamos uma variรกvel myItem e chamamos o mรฉtodo match.
- verificamos se myItem รฉ verdadeiro usando e fazemos alguma lรณgica no lado direito da seta gorda โ=>โ.
- usamos o sublinhado para corresponder a qualquer coisa que nรฃo corresponda a nenhuma das instruรงรตes case que definimos no cรณdigo.
Com as classes Case, podemos ir ainda mais longe e desestruturar a classe para obter campos dentro do objeto.
Ao usar a palavra-chave selada para definir nossas classes, temos o benefรญcio de fazer com que o compilador verifique exaustivamente os casos que tentamos comparar e nos avise se esquecermos de lidar com um caso especรญfico.
Imutabilidade
ร possรญvel criar valores que nรฃo podem ser alterados por outras funรงรตes no Scala usando a palavra-chave val. Isto รฉ conseguido em Java usando a palavra-chave final. No Scala, fazemos isso usando uma palavra-chave val ao criar uma variรกvel em vez de usar var, que รฉ a alternativa que usarรญamos para criar uma variรกvel mutรกvel.
Uma variรกvel definida usando a palavra-chave val รฉ somente leitura, enquanto uma definida com var pode ser lida e alterada por outras funรงรตes ou arbitrariamente pelo usuรกrio no cรณdigo.
var changeableVariable = 8 changeableVariable =10 //the compiler doesn't complain, and the code compiles successfully println(changeableVariable) //10 val myNumber = 7 myNumber = 4 //if we try this the code won't compile
Tentar atribuir um valor a myNumber depois de declarรก-lo como val gera um erro em tempo de compilaรงรฃo ou โreatribuiรงรฃo para valโ.
Por que usar Imutabilidade?
A imutabilidade nos ajuda a evitar que o cรณdigo e outros programadores alterem nossos valores inesperadamente, o que levaria a resultados inesperados se eles pretendessem usar o valor que armazenamos, eles poderiam, em vez disso, fazer uma cรณpia dele. Dessa forma, evitam-se bugs que podem ser causados โโpor mรบltiplos atores alterando a mesma variรกvel.
Classes e Objetos
Todos nรณs sabemos que os objetos sรฃo entidades do mundo real e a classe รฉ um modelo que define os objetos. As classes tรชm estado e comportamentos. Os estados sรฃo valores ou variรกveis. Os comportamentos sรฃo os mรฉtodos em Scala.
Vejamos como vocรช pode definir uma classe, instanciรก-la e usรก-la usando Scala.
Aqui, a classe chamada Rectangle, que possui duas variรกveis โโ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 instanciou 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 rectangle with length as $length and breadth as $breadth"
}
object RectObject {
def main(args: Array[String]) {
val rect = new Rectangle(4, 5)
println(rect.toString)
println(rect.getArea)
}
}
Todos os campos e mรฉtodos sรฃo pรบblicos por padrรฃo no Scala. ร essencial usar override porque o mรฉtodo toString รฉ definido para Object em Scala.
Heranรงa
Scala tem vรกrios tipos de heranรงa (como รบnica, multinรญvel, mรบltipla, hierรกrquica, hรญbrida) que compartilham muito em comum com formas tradicionais encontradas em Java. Vocรช pode herdar tanto de classes quanto de caracterรญsticas. Vocรช pode herdar os membros de uma classe para outra classe usando a palavra-chave โextendsโ. Isso permite a reutilizaรงรฃo.
ร possรญvel herdar de uma classe ou de vรกrias classes. Tambรฉm รฉ possรญvel herdar de subclasses que possuem suas superclasses, criando uma hierarquia de heranรงa no processo.
No exemplo Scala abaixo, a classe Base รฉ Circle e a classe derivada รฉ Sphere. Um cรญrculo possui um valor chamado raio, que รฉ herdado da classe Sphere. 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
}
}
Abstraรงรฃo
No Scala, podemos criar mรฉtodos abstratos e campos membros usando classes e caracterรญsticas abstratas. Dentro de classes e caracterรญsticas abstratas, podemos definir campos abstratos sem necessariamente 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 a caracterรญstica ou classe abstrata. Vocรช pode usar caracterรญsticas para criar contratos sobre o que nosso aplicativo deve ser capaz de fazer e implementar esses mรฉtodos posteriormente.
trait DatabaseService{
def addItemName(itemName:String)
def removeItem(itemId:Int)
def updateItem(itemId:Int, newItemName:String)
}
Dessa forma, podemos planejar a aparรชncia de nosso aplicativo sem implementar os mรฉtodos que podem nos ajudar a imaginar como serรฃo os vรกrios mรฉtodos. Ele segue um padrรฃo conhecido como programaรงรฃo para abstraรงรตes e nรฃo para a implementaรงรฃo real.
A classe precedida pela palavra-chave abstract pode conter mรฉtodos abstratos e nรฃo abstratos. Porรฉm, heranรงas mรบltiplas nรฃo sรฃo suportadas na classe abstrata. Portanto, vocรช pode estender no mรกximo uma classe abstrata.
Objetos Singleton
Um Singleton รฉ uma classe que sรณ รฉ instanciada uma vez em um programa. ร de um padrรฃo de programaรงรฃo popular e รบtil conhecido como โpadrรฃo singletonโ. ร รบtil na criaรงรฃo de instรขncias que devem ter vida longa e serรฃo comumente acessadas em todo o programa, cujo estado รฉ essencial na coordenaรงรฃo dos eventos de um sistema. Criar tal classe no Scala รฉ fรกcil, pois o Scala nos fornece um meio simples de criar singletons usando a palavra-chave object.
object UserProfile{
var userName=""
var isLoggedIn:Boolean = false
}
Podemos entรฃo referenciar esse objeto em todo o nosso programa com a garantia de que todas as partes do nosso programa verรฃo os mesmos dados, pois hรก 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 no Scala, por isso vocรช precisa usar objetos singleton, que agem como membros estรกticos de uma classe.
Classes implรญcitas
Classes implรญcitas sรฃo as novas funcionalidades adicionadas apรณs a versรฃo 2.1. ร principalmente para adicionar novas funcionalidades ร s classes fechadas.
A palavra-chave implรญcita deve ser definida em uma classe, objeto ou caracterรญstica. O construtor primรกrio de uma classe implรญcita deve ter exatamente um argumento em sua primeira lista de parรขmetros. Tambรฉm pode incluir uma lista de parรขmetros implรญcitos adicionais.
No exemplo de Scala abaixo, uma nova funcionalidade para substituir vogais de uma String por * foi adicionada.
object StringUtil {
implicit class StringEnhancer(str: String) {
def replaceVowelWithStar: String = str.replaceAll("[aeiou]", "*")
}
}
Vocรช precisa importar na classe onde estรก usando.
import StringUtil.StringEnhancer
object ImplicitEx extends App {
val msg = "This is Guru99!"
println(msg.replaceVowelWithStar)
}
Programaรงรฃo Orientada a Objetos (OOP) vs. Programaรงรฃo Funcional (FP)
Na POO, os programas sรฃo construรญdos agrupando dados e as funรงรตes que operam nesses dados em unidades altamente conectadas. Os objetos carregam seus dados nos campos e mรฉtodos que operam neles. Neste estilo de programaรงรฃo, a principal abstraรงรฃo sรฃo os dados, pois os mรฉtodos criados tรชm como objetivo operar nos dados.
Programaรงรฃo funcional, por outro lado, separa os dados e as funรงรตes que operam nos dados. Isso permite que os desenvolvedores tratem as funรงรตes como abstraรงรฃo e forรงa motriz ao modelar programas.
Scala permite a programaรงรฃo funcional tendo funรงรตes como cidadรฃos de primeira classe, permitindo que sejam passadas como valores para outras funรงรตes e tambรฉm retornadas como valores. A combinaรงรฃo desses dois paradigmas fez do Scala uma รณtima opรงรฃo na construรงรฃo de software complexo em diversos setores, como Data Science.
Frameworks importantes no Scala
Aqui estรฃo alguns frameworks importantes do Scala
- Jogar รฉ uma estrutura de aplicativo da web de cรณdigo aberto que usa Arquitetura MVC. Lanรงado em 2007 e agora licenciado sob Apache, tornou-se o framework mais popular no GitHub em 2013. Empresas como LinkedIn, Walmart, Samsung, Eero usam este framework.
- Levantar รฉ outro framework web gratuito escrito em Scala lanรงado em 2007. Foursquare usa o framework Lift. ร de alto desempenho e mais rรกpido de construir uma estrutura.
- Como
- Gatos - Leecork
- Spark
Suporte de simultaneidade
- Os valores em Scala sรฃo imutรกveis โโpor padrรฃo. Isso o torna muito adaptรกvel ao ambiente simultรขneo.
- Existem muitos recursos no Scala que o tornam ideal para aplicativos simultรขneos.
- Futuros e Promessas facilitam o processamento de dados de forma assรญncrona, apoiando assim o paralelismo.
- Akka โ kit de ferramentas que usa modelo de simultaneidade de ator. Existem vรกrios atores que atuam quando recebem mensagens.
- Simultaneidade usando threads de Java tambรฉm pode ser suportado em Scala.
- O processamento de fluxo รฉ outro รณtimo recurso que permite o processamento contรญnuo de dados em tempo real.
Scala tem algumas das melhores bibliotecas de simultaneidade do Java ecossistema.
- Nativo Java tรณpicos
- Fibras de bibliotecas como Vertex
- ZIO โ uma biblioteca que possui primitivas para nos ajudar a lidar com simultaneidade e computaรงรฃo assรญncrona
- STM โ Transaรงรฃo
- Futuro โ embutido na linguagem Scala
Java vs.
Aqui estรฃo os principais diferenรงa entre Java e escala.
| Scala | Java |
|---|---|
| Mais compacto e conciso | Pedaรงos de cรณdigo comparativamente maiores |
| Projetado e desenvolvido para ser uma linguagem orientada a objetos e funcionais. Suporta uma ampla variedade de recursos de programaรงรฃo funcional, como simultaneidade e imutabilidade. |
Originalmente desenvolvida como uma linguagem orientada a objetos e comeรงou a oferecer suporte a recursos de programaรงรฃo funcional nos รบltimos dias. Ainda nรฃo รฉ forte como linguagem de programaรงรฃo funcional. |
| Usa modelo de ator para suportar simultaneidade que รฉ moderna | Usa o modelo convencional baseado em thread para simultaneidade. |
| Suporta estruturas โ Play, Lift | Suporta Spring, Grails e muito mais |
| Suporta avaliaรงรฃo preguiรงosa | Nรฃo suporta avaliaรงรฃo preguiรงosa |
| Nenhum membro estรกtico | Contรฉm membros estรกticos |
| Suporta sobrecarga do operador | Nรฃo suporta sobrecarga do operador |
| A compilaรงรฃo do cรณdigo-fonte รฉ comparativamente lenta | A compilaรงรฃo do cรณdigo-fonte รฉ mais rรกpida que Scala |
| Caracterรญsticas โ agir como Java 8 interfaces | Java 8 interfaces tentam preencher a lacuna entre classes e interfaces |
| ร necessรกrio reescrever | Nรฃo รฉ necessรกrio reescrever |
| Nenhuma garantia sobre os cรณdigos livres de bugs | Garantia completa de defeitos menores |
| Suporta compatibilidade com versรตes anteriores. | Scala nรฃo suporta compatibilidade com versรตes anteriores. |
| Operators sรฃo tratados de forma diferente em Java e nรฃo sรฃo chamadas de mรฉtodo. | Todos os operadores nas entradas sรฃo atravรฉs de um mรฉtodo chamado em Scala. |
| Suporta mรบltiplas heranรงas usando classes, mas nรฃo por classes abstratas | Nรฃo suporta mรบltiplas heranรงas usando classes, mas sim por interfaces |
| O cรณdigo รฉ escrito em formato compacto. | O cรณdigo รฉ escrito em formato longo. |
| Scala nรฃo contรฉm a palavra-chave estรกtica. | Java contรฉm a palavra-chave estรกtica. |
Resumo
Neste tutorial, vocรช aprendeu como comeรงar a usar Scala. Vocรช tambรฉm aprendeu os recursos funcionais e orientados a objetos. Vocรช tambรฉm descobriu as semelhanรงas e diferenรงas entre Java e Scala. Este tutorial deve ter ajudado vocรช com uma ampla variedade de exemplos bem demonstrados.






















