Eu tenho uma pergunta muito simples - quando devemos aplicar a nova palavra-chave ao criar objetos no Scala? É quando tentamos instanciar apenas objetos Java?
Respostas:
Use a new
palavra - chave quando quiser se referir ao class
próprio construtor de:
class Foo { }
val f = new Foo
Omita new
se você estiver se referindo ao apply
método do objeto complementar :
class Foo { }
object Foo {
def apply() = new Foo
}
// Both of these are legal
val f = Foo()
val f2 = new Foo
Se você fez uma aula de caso:
case class Foo()
Scala secretamente cria um objeto companheiro para você, transformando-o neste:
class Foo { }
object Foo {
def apply() = new Foo
}
Então você pode fazer
f = Foo()
Por último, lembre-se de que não há regra que diga que o apply
método complementar deve ser um proxy para o construtor:
class Foo { }
object Foo {
def apply() = 7
}
// These do different things
> println(new Foo)
test@5c79cc94
> println(Foo())
7
E, já que você mencionou as classes Java: sim - as classes Java raramente têm objetos companheiros com um apply
método, então você deve usar new
e o construtor da classe real.
É quando tentamos instanciar apenas objetos java?
De modo nenhum. Há dois casos gerais em que você omite new
na escala. Com objetos singleton (que geralmente são usados para armazenar funções estáticas e como uma espécie de fábrica semelhante ao que você pode ver em java):
scala> object LonelyGuy { def mood = "sad" }
defined module LonelyGuy
scala> LonelyGuy
res0: LonelyGuy.type = LonelyGuy$@3449a8
scala> LonelyGuy.mood
res4: java.lang.String = sad
Com classes de caso (na verdade, embaixo há classe + objeto = padrão companheiro , por exemplo, tendo classe e objeto com o mesmo nome):
scala> case class Foo(bar: String)
defined class Foo
scala> Foo("baz")
res2: Foo = Foo(baz)
Portanto, quando você trabalha com classes simples, as regras são as mesmas do Java.
scala> class Foo(val bar: String)
defined class Foo
scala> new Foo("baz")
res0: Foo = Foo@2ad6a0
// will be a error
scala> Foo("baz")
<console>:8: error: not found: value Foo
Foo("baz")
Bônus, existe uma classe anônima em scala, que pode ser construída assim:
scala> new { val bar = "baz" }
res2: java.lang.Object{val bar: java.lang.String} = $anon$1@10ee5b8
scala> res2.bar
res3: java.lang.String = baz
É quando tentamos instanciar apenas objetos Java?
Com Scala 3 (que deve ser lançado em meados de 2020, oito anos depois), baseado em Dotty : nunca.
Scala 3 irá eliminar " new
", como neste tópico
Os aplicativos criadores permitem usar a sintaxe de chamada de função simples para criar instâncias de uma classe, mesmo se não houver nenhum método de aplicação implementado.
Exemplo:
class StringBuilder(s: String) {
def this() = this(s)
}
StringBuilder("abc") // same as new StringBuilder("abc")
StringBuilder() // same as new StringBuilder()
Os aplicativos criadores generalizam uma funcionalidade fornecida até agora apenas para classes de caso, mas o mecanismo como isso é obtido é um pouco diferente.
Em vez de um método de aplicação gerado automaticamente, adicionamos uma nova interpretação possível a uma chamada de funçãof(args)
.