Как я могу обработать эту ошибку, которая не является подтипом переопределенной

Я пытаюсь написать проверяемый интерфейс формы в 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> в достоверном это говорит;

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> в достоверном это говорит;

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 используются из класса внутри себя. Я не хочу менять это в отношении использования библиотеки.

Есть ли в любом случае использовать in а также out ключевые слова вместе или, может быть, есть другой способ достижения моей цели.

1 ответ

Решение

Вы могли бы сделать абстрактный класс 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"
        }
    })
}
Другие вопросы по тегам