我正在看这段代码
def loginForm = Form(mapping("username" -> text, "password" -> text)
(LoginRequest.apply)(LoginRequest.unapply))
case class LoginRequest(username:String, password:String)
以下是Play
def mapping[R, A1, A2](a1: (String, Mapping[A1]),
a2: (String, Mapping[A2]))
(apply: Function2[A1, A2, R])
(unapply: Function1[R, Option[(A1, A2)]]):
Mapping[R] = {
new ObjectMapping2(apply, unapply, a1, a2)
}
我想找出什么
LoginRequest.apply
实际意味着什么
ObjectMapping2(LoginRequest.apply, LoginRequest.unapply, "username" -> text, "password" -> text)
DO
答案 0 :(得分:2)
您的LoginRequest
是case class,因此包含由编译器自动插入的方法apply
和unapply
。 Play需要他们知道如何从映射中构造和解构域对象。如果您有一些自定义代码,则需要自定义应用/取消应用,但由于您正在使用案例类(这是正确的做法),您可以简单地传递其开箱即用的应用和取消应用函数。
所以,为了回答你的第一个问题,LoginRequest.apply
是一个可用于每个案例类的apply函数的调用。
回答你的第二个问题,
ObjectMapping2(LoginRequest.apply, LoginRequest.unapply, "username" -> text, "password" -> text)`
表示将从“username”和“password”字符串创建一个新的LoginRequest
,方法是将它们传递给LoginRequest.apply
,这是LoginRequest
案例类的构造函数。它还说明使用LoginRequest
解析LoginRequest.unapply
,这将返回Option[(String, String)]
(每个参数都有一个字符串,在您的情况下是用户名和密码)。
编辑:
我在评论中得到了合理的警告,以便更加准确。因此,在定义案例类时,编译器将在其伴随对象中自动生成apply()
和unapply()
。您始终可以在您定义的任何类的任何伴随对象中包含这些方法。在这种情况下,编译器会为您完成。方法apply()
在某种意义上是“特殊的”,它允许特殊的语法糖:而不是调用Something.apply()
,它也可以简单地调用Something()
。
请注意,apply()
和unapply()
不会被覆盖或实施;你(或者在这种情况下是编译器)只是从头开始定义它们就像任何其他自定义方法一样。但它是Scala编译器中允许语法糖的“技巧”。因此,如果您在MyClass的伴随对象中定义方法apply()
,您当然可以按照MyClass.apply(whatever)
的常规方式调用它,也可以MyClass(whatever)
(这是技巧部分) 。
即使您有时不了解它,也会一直使用它 - 例如,编译器List(1, 2, 3)
实际上将List.apply(1, 2, 3)
置于List.apply()
之内。这个技巧允许程序员编写更漂亮,更易读的代码(copy
很难看,不是吗?)
与此特定问题无关,但我也要提一下 - 编译器还会为案例类添加一些其他方法:toString
,equals
,hashCode
和apply
。与unapply
和apply
不同,这些方法会添加到类中(因此不会调用unapply
和class ViewController: UIViewController
{
@IBOutlet weak var marqueeLabel: MarqueeLabel!
override func viewDidLoad() {
super.viewDidLoad()
self.marqueeLabel.tag = 101
self.marqueeLabel.type = .Continuous
self.marqueeLabel.speed = .Duration(5)
self.marqueeLabel.animationCurve = .EaseInOut
self.marqueeLabel.fadeLength = 10.0
self.marqueeLabel.leadingBuffer = 30.0
self.marqueeLabel.trailingBuffer = 20.0
self.marqueeLabel.restartLabel()
}
}
等伴随对象,需要在case类的实例上调用。)