Я никогда не понимал этого из придуманных, неуместных и глагольных существительных (у AddTwo
класса есть класс, apply
который добавляет два!) Примеров.
Я понимаю, что это синтаксический сахар, поэтому (я понял из контекста) он должен был быть разработан, чтобы сделать некоторый код более интуитивным.
Какой смысл дает класс с apply
функцией? Для чего он используется и в каких целях он делает код лучше (демаршаллинг, глагольные существительные и т. Д.)?
Как это помогает при использовании в объекте-компаньоне?
Ответы:
У математиков есть свои маленькие забавные способы, поэтому вместо того, чтобы говорить «тогда мы вызываем функцию,
f
передавая ееx
в качестве параметра», как сказали бы мы, программисты, они говорят о «применении функцииf
к ее аргументуx
».apply
служит для устранения разрыва между объектно-ориентированной и функциональной парадигмами в Scala. Каждая функция в Scala может быть представлена как объект. Каждая функция также имеет тип OO: например, функция, которая принимаетInt
параметр и возвращаетInt
тип, будет иметь тип OOFunction1[Int,Int]
.Поскольку в Scala все является объектом,
f
теперь его можно рассматривать как ссылку наFunction1[Int,Int]
объект. Например, мы можем вызватьtoString
метод, унаследованный отAny
, что было бы невозможно для чистой функции, потому что у функций нет методов:Или мы можем определить другой
Function1[Int,Int]
объект, вызвавcompose
методf
и связав две разные функции вместе:Теперь, если мы хотим фактически выполнить функцию или, как математик говорит «применить функцию к ее аргументам», мы бы вызвали
apply
методFunction1[Int,Int]
объекта:Запись
f.apply(args)
каждый раз, когда вы хотите выполнить функцию, представленную в виде объекта, является объектно-ориентированным способом, но добавит много беспорядка в код, не добавляя много дополнительной информации, и было бы неплохо иметь возможность использовать более стандартную запись, такую как какf(args)
. Вот где Scala-компилятор входит, и когда у нас есть ссылкаf
на объект функции и пишется,f (args)
чтобы применить аргументы к представленной функции, компилятор молча расширяетf (args)
вызов метода объектаf.apply (args)
.Каждая функция в Scala может рассматриваться как объект, и она работает по-другому - каждый объект может рассматриваться как функция, если у него есть
apply
метод. Такие объекты можно использовать в обозначениях функций:Есть много случаев использования, когда мы хотим рассматривать объект как функцию. Наиболее распространенным сценарием является фабричный шаблон . Вместо добавления беспорядка в код, используя фабричный метод, мы можем
apply
возражать против набора аргументов, чтобы создать новый экземпляр связанного класса:Так что
apply
метод - это просто удобный способ сократить разрыв между функциями и объектами в Scala.источник
class Average[YType](yZeroValue:YType)
. Как передать YType из его объекта, поскольку объекты не могут принимать параметры типа?apply
иunapply
методы к сопутствующему объекту класса (среди прочего). Таким образом , определив класс с одной строкой , как этоcase class Car(make:String, model: String, year: Short, color: String)
позволяет создавать новые объекты класса Car, просто:val myCar = Car("VW","Golf",1999,"Blue")
. Это сокращение дляCar.apply(...)
every object can be treated as a function, provided it has the apply method
- так много сейчас имеет смысл.Это происходит из-за того, что вы часто хотите применить что-то к объекту. Более точный пример - один из заводов. Когда у вас есть фабрика, вы хотите применить к ней параметр для создания объекта.
Ребята из Scala думали, что, как это часто бывает во многих ситуациях, было бы неплохо иметь ярлык для вызова
apply
. Таким образом, когда вы передаете параметры непосредственно объекту, это обескураживается, как если бы вы передавали эти параметры функции apply этого объекта:Это часто используется в сопутствующем объекте, чтобы обеспечить хороший фабричный метод для класса или признака, вот пример:
Из стандартной библиотеки scala вы можете посмотреть, как
scala.collection.Seq
это реализовано:Seq
это черта, поэтомуnew Seq(1, 2)
не компилируется, но благодаря объекту-компаньону и apply вы можете вызывать,Seq(1, 2)
и реализация выбирается объектом-компаньоном.источник
Вот небольшой пример для тех, кто хочет быстро просмотреть
источник