Я новичок в скале. Что означает следующий синтаксис?
case class User(val id: Long)(val username: String)
Я читал о каррировании в scala, но объясните, пожалуйста, как это связано с конструкцией выше (если связано). Спасибо.
Я новичок в скале. Что означает следующий синтаксис?
case class User(val id: Long)(val username: String)
Я читал о каррировании в scala, но объясните, пожалуйста, как это связано с конструкцией выше (если связано). Спасибо.
Точно так же, как частично примененные функции, конструктор (который является функцией от своих аргументов к сконструированному типу) может быть частично применен, в этом случае:
scala> case class User(val id: Long)(val username: String)
defined class User
scala> val userBuilder = User(123L) _
userBuilder: String => User = <function1>
Обратите внимание на тип результирующего userBuilder
— это функция от String
(оставшийся параметр) до User
.
Теперь, подобно частично примененным функциям, вы можете применить этот результат к String и получить экземпляр User
:
scala> val user = userBuilder("a")
user: User = User(123)
scala> user.username
res1: String = a
Когда это полезно?
Если вы хотите создать множество экземпляров с общими значениями для подмножества аргументов, например:
case class Person(lastName: String)(val firstName: String)
class Family(lastName: String, firstNames: List[String]) {
def getMembers: List[Person] = {
val creator = Person(lastName) _ // will be reused for each first name!
firstNames.map(creator)
}
}
Если вы хотите использовать один аргумент в качестве значения по умолчанию для другого:
case class Measure(min: Int)(val max: Int = min*2)
Measure(5)() // max = 10
Measure(5)(12) // default overridden, max = 12
Если вы хотите использовать implicit
аргументов, которые должны находиться в отдельном, последнем списке аргументов функции, как описано в Спецификация языка Scala (глава 7.2):
Метод или конструктор может иметь только один список неявных параметров, и это должен быть последний заданный список параметров.
Он позволяет построить объект поэтапно.
val user = User(123L) _ // user now has only the ID
// later on
val completeUser = user("moreo") // user now also has the username
Обычно это полезно, когда вы хотите, чтобы ваш объект следовал интерфейсу, но вам нужно передать дополнительные параметры, поэтому вы сначала инициализируете свой объект с этими параметрами, а затем получаете функцию, которая может следовать интерфейсу.
User(123L) _
, чтобы получить частично примененный конструктор.
- person Tzach Zohar; 11.07.2016
user
здесь не User
, а функция: String => User
- person Dima; 11.07.2016