我正在尝试在Kotlin中编写一些可验证的表单接口。在验证部分,我正在使用https://github.com/kamedon/Validation。
这是我要运行的非常简单的代码;
import com.kamedon.validation.Validation
abstract class Validatable {
abstract val validation: Validation<Any>
fun validate() = validation.validate(this)
}
class LoginForm : Validatable() {
val name: String = "Onur"
val age: Int = 23
override val validation = Validation<LoginForm> {
"name" {
be { name.length >= 5 } not "5 characters or more"
be { name.length <= 10 } not "10 characters or less"
}
"age" {
be { age >= 20 } not "Over 20 years old"
}
}
}
fun main(args: Array<String>) {
val user = LoginForm()
val result = user.validate()
println(result)
}
这段代码给了我
Type of 'validation' is not a subtype of the overridden property 'public abstract val validation: Validation<Any> defined in Validatable'
如果我在Validatable中使用Validation<out Any>
,它会说;
Kotlin: Out-projected type 'Validation<out Any>' prohibits the use of 'public final fun validate(value: T): Map<String, List<String>> defined in com.kamedon.validation.Validation'
如果我在Validatable中使用Validation<in Any>
,它会说;
Kotlin: Type of 'validation' is not a subtype of the overridden property 'public abstract val validation: Validation<in Any> defined in Validatable'
如果我在LoginForm中使用Validation<Any>
而不是Validation<LoginForm>
,则代码将运行,但这次validation
中的名称和年龄是从其内部的类使用的。我不想就图书馆的使用情况对此进行更改。
总有没有同时使用in
和out
关键字,或者还有另一种方法可以实现我的目标。
答案 0 :(得分:2)
您可以使抽象类Validatable
成为通用类,并使子类提供一个对象,该对象同时公开Validation
对象和本身作为target
进行验证,例如
abstract class Validatable<T> {
protected class ValidationInfo<T>(val target: T, val validation: Validation<T>)
protected abstract val validationInfo: ValidationInfo<T>
fun validate() = validationInfo.let { it.validation.validate(it.target) }
}
class LoginForm : Validatable<LoginForm>() {
val name: String = "Onur"
val age: Int = 23
override val validationInfo = ValidationInfo(this, Validation {
"name" {
be { name.length >= 5 } not "5 characters or more"
be { name.length <= 10 } not "10 characters or less"
}
"age" {
be { age >= 20 } not "Over 20 years old"
}
})
}