Generics 我如何处理这件事;不是重写的子类型;错误

Generics 我如何处理这件事;不是重写的子类型;错误,generics,kotlin,generic-variance,type-projection,Generics,Kotlin,Generic Variance,Type Projection,我试图在Kotlin中编写一些可验证的表单接口。在我使用的验证部分 下面是我试图运行的非常简单的代码 import com.kamedon.validation.Validation abstract class Validatable { abstract val validation: Validation<Any> fun validate() = validation.validate(this) } class LoginForm : Validat

我试图在Kotlin中编写一些可验证的表单接口。在我使用的验证部分

下面是我试图运行的非常简单的代码

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)
}
import com.kamedon.validation.validation
抽象类可验证{
摘要val验证:验证
fun validate()=validation.validate(此)
}
类LoginForm:Validatable(){
val名称:String=“Onur”
val年龄:Int=23
覆盖val验证=验证{
“姓名”{
{name.length>=5}不是“5个字符或更多”
是{name.length=20}不是“超过20岁”
}
}
}
趣味主线(args:Array){
val user=LoginForm()
val result=user.validate()
println(结果)
}
这个密码给了我

Type of 'validation' is not a subtype of the overridden property 'public abstract val validation: Validation<Any> defined in Validatable'
类型“validation”不是重写属性“public abstract val validation:Validable中定义的验证”的子类型
如果我在Validable中使用
验证
,它会说

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'
Kotlin: Type of 'validation' is not a subtype of the overridden property 'public abstract val validation: Validation<in Any> defined in Validatable'
Kotlin:Out projected type“Validation”禁止使用“public final fun validate(value:T):com.kamedon.Validation.Validation中定义的映射”
如果我在Validable中使用
验证
,它会说

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'
Kotlin: Type of 'validation' is not a subtype of the overridden property 'public abstract val validation: Validation<in Any> defined in Validatable'
Kotlin:“validation”的类型不是重写属性“public abstract val validation:Validable中定义的验证”的子类型
如果在LoginForm中使用
验证
而不是
验证
,则代码会运行,但这次
验证
中的名称和年龄是从类本身中使用的。我不想在图书馆的使用方面改变这一点


是否可以同时使用
in
out
关键字,或者是否有其他方法来实现我的目标

您可以使抽象类
可验证
成为泛型类,并使子类提供一个对象,该对象既公开
验证
对象,也公开自身作为要验证的
目标,例如

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"
        }
    })
}
可验证的抽象类{
受保护类ValidationInfo(val目标:T,val验证:验证)
受保护的抽象val validationInfo:validationInfo
fun validate()=validationInfo.let{it.validation.validate(it.target)}
}
类LoginForm:Validatable(){
val名称:String=“Onur”
val年龄:Int=23
覆盖val validationInfo=validationInfo(此为验证{
“姓名”{
{name.length>=5}不是“5个字符或更多”
是{name.length=20}不是“超过20岁”
}
})
}

您可以使抽象类
可验证
成为一个泛型类,并使子类提供一个对象,该对象既公开
验证
对象,也公开自身作为要验证的
目标,例如

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"
        }
    })
}
可验证的抽象类{
受保护类ValidationInfo(val目标:T,val验证:验证)
受保护的抽象val validationInfo:validationInfo
fun validate()=validationInfo.let{it.validation.validate(it.target)}
}
类LoginForm:Validatable(){
val名称:String=“Onur”
val年龄:Int=23
覆盖val validationInfo=validationInfo(此为验证{
“姓名”{
{name.length>=5}不是“5个字符或更多”
是{name.length=20}不是“超过20岁”
}
})
}

我尝试了这个,但这次验证。验证(这个)不起作用。它需要
作为
T
但接收
可验证的
。编译器为此抱怨。是的,你是对的,我错了。我已经用一种稍微不同的方法更新了我的答案,尽管我认为一定有更好的方法,非常聪明的解决方案。谢谢。我试过了,但这次验证。验证(这个)不起作用。它需要
作为
T
但接收
可验证的
。编译器为此抱怨。是的,你是对的,我错了。我已经用一种稍微不同的方法更新了我的答案,尽管我认为一定有更好的方法,非常聪明的解决方案。非常感谢。