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 newpalavra - chave quando quiser se referir ao classpróprio construtor de:
class Foo { }
val f = new Foo
Omita newse você estiver se referindo ao applymé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 applymétodo, então você deve usar newe o construtor da classe real.
É quando tentamos instanciar apenas objetos java?
De modo nenhum. Há dois casos gerais em que você omite newna 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).