0

我正在尝试在 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'

如果我Validation<out Any>在 Validatable 中使用它会说;

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'

如果我Validation<in Any>在 Validatable 中使用它会说;

Kotlin: Type of 'validation' is not a subtype of the overridden property 'public abstract val validation: Validation<in Any> defined in Validatable'

如果我使用Validation<Any>而不是Validation<LoginForm>在 LoginForm 中,代码会运行,但这次内部的名称和年龄validation是从内部的类中使用的。关于图书馆的使用,我不想改变这一点。

反正有没有一起使用inout关键字,或者可能有另一种方法来实现我的目标。

4

1 回答 1

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"
        }
    })
}
于 2018-11-21T08:08:37.093 回答