Eu nunca entendi a partir dos substantivos não ordenados e verbais (uma AddTwo
classe tem umapply
exemplos que adiciona dois!).
Entendo que é um açúcar sintático, então (deduzi do contexto) ele deve ter sido projetado para tornar algum código mais intuitivo.
Qual o significado de uma classe com uma apply
função? Para que é usado e para quais propósitos ele melhora o código (remoção da correspondência, verbos verbais etc.)?
como isso ajuda quando usado em um objeto complementar?
Respostas:
Os matemáticos têm suas próprias maneiras engraçadas, então, em vez de dizer "então chamamos a função
f
passandox
como parâmetro", como diríamos os programadores, eles falam sobre "aplicar a funçãof
ao seu argumentox
".apply
serve ao propósito de fechar a lacuna entre paradigmas orientados a objetos e funcionais em Scala. Toda função no Scala pode ser representada como um objeto. Toda função também possui um tipo OO: por exemplo, uma função que pega umInt
parâmetro e retorna umInt
terá o tipo OOFunction1[Int,Int]
.Como tudo é um objeto no Scala
f
agora pode ser tratado como uma referência aoFunction1[Int,Int]
objeto. Por exemplo, podemos chamar otoString
método herdado deAny
, que seria impossível para uma função pura, porque funções não possuem métodos:Ou podemos definir outro
Function1[Int,Int]
objeto chamando ocompose
métodof
e encadeando duas funções diferentes:Agora, se queremos realmente executar a função, ou, como matemático diz "aplicar uma função aos seus argumentos", chamaríamos o
apply
método noFunction1[Int,Int]
objeto:Escrever
f.apply(args)
toda vez que você deseja executar uma função representada como um objeto é a maneira Orientada a Objetos, mas adicionaria muita confusão ao código sem adicionar muita informação adicional e seria bom poder usar uma notação mais padrão, como comof(args)
. É aí que o compilador Scala intervém e sempre que temos uma referênciaf
a um objeto de função e escrevemosf (args)
para aplicar argumentos à função representada, o compilador se expande silenciosamentef (args)
para a chamada do método de objetof.apply (args)
.Toda função no Scala pode ser tratada como um objeto e funciona da outra maneira - todo objeto pode ser tratado como uma função, desde que tenha o
apply
método. Tais objetos podem ser usados na notação de função:Existem muitos casos de uso em que queremos tratar um objeto como uma função. O cenário mais comum é um padrão de fábrica . Em vez de adicionar confusão ao código usando um método factory, podemos
apply
objetar um conjunto de argumentos para criar uma nova instância de uma classe associada:Portanto, o
apply
método é apenas uma maneira útil de fechar a lacuna entre funções e objetos no Scala.fonte
class Average[YType](yZeroValue:YType)
. Como você passa o YType de seu objeto, uma vez que os objetos não podem receber parâmetros de tipo?apply
eunapply
métodos a um objeto complementar da classe (entre outras coisas). Assim, definindo uma classe com apenas uma linha como estacase class Car(make:String, model: String, year: Short, color: String)
faz com que seja possível produzir novos objetos da classe Car por apenas:val myCar = Car("VW","Golf",1999,"Blue")
. Isto é uma abreviação paraCar.apply(...)
every object can be treated as a function, provided it has the apply method
- tanto agora faz sentido.Vem da ideia de que você frequentemente deseja aplicar algo a um objeto. O exemplo mais preciso é o das fábricas. Quando você tem uma fábrica, deseja aplicar parâmetro a ele para criar um objeto.
Os caras do Scala pensaram que, como ocorre em muitas situações, pode ser bom ter um atalho para chamar
apply
. Portanto, quando você fornece parâmetros diretamente a um objeto, é sugerido como se você passasse esses parâmetros para a função de aplicação desse objeto:Geralmente é usado no objeto complementar, para fornecer um bom método de fábrica para uma classe ou característica, eis um exemplo:
Na biblioteca padrão da scala, você pode ver como
scala.collection.Seq
é implementado:Seq
é uma característica, portantonew Seq(1, 2)
, não será compilada, mas graças ao objeto complementar e à aplicação, você pode chamarSeq(1, 2)
e a implementação é escolhida pelo objeto complementar.fonte
Aqui está um pequeno exemplo para quem quer ler rapidamente
fonte