Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reflection Kotlin中KProperty1的泛型扩展_Reflection_Kotlin_Kotlin Reflect - Fatal编程技术网

Reflection Kotlin中KProperty1的泛型扩展

Reflection Kotlin中KProperty1的泛型扩展,reflection,kotlin,kotlin-reflect,Reflection,Kotlin,Kotlin Reflect,我有以下代码: import kotlin.reflect.KProperty1 infix fun <T, R> KProperty1<T, R>.eq(value: R) { println(this.name + " = $value") } infix fun <T, R> KProperty1<T, R>.eq(value: KProperty1<T, R>) { println(this.name +

我有以下代码:

import kotlin.reflect.KProperty1


infix fun <T, R> KProperty1<T, R>.eq(value: R) {
    println(this.name + " = $value")
}

infix fun <T, R> KProperty1<T, R>.eq(value: KProperty1<T, R>) {
    println(this.name + " = " + value.name)
}

data class Person(val age: Int, val name: String, val surname: String?)

fun main() {
    Person::age eq 1  // Valid. First function
    Person::name eq "Johan"  // Valid. First function
    Person::name eq Person::name  // Valid. Second function
    Person::age eq 1.2f  // Valid, but it shouldn't be. First function
    Person::age eq Person::name  // Valid, but it shouldn't be. First function
    Person::surname eq null  // Invalid, but it should be. Second function, but it should be first
}
导入kotlin.reflect.KProperty1
中缀乐趣KProperty1.eq(值:R){
println(this.name+“=$value”)
}
infix fun KProperty1.eq(值:KProperty1){
println(this.name+“=”+value.name)
}
数据类人员(val年龄:Int,val名称:String,val姓氏:String?)
主要内容(){
Person::age eq 1//有效。第一个函数
Person::name eq“Johan”//Valid.第一个函数
Person::name eq Person::name//Valid.Second函数
Person::age eq 1.2f//有效,但不应该是。第一个函数
Person::age eq Person::name//有效,但不应为。第一个函数
Person::姓氏eq null//无效,但应为。第二个函数,但应为第一个
}
我正在尝试使用泛型为
KProperty1
类创建扩展函数,但我的泛型与我预期的不匹配
main()
列出了这两个函数的一些用法,最后列出了3个意外的结果,并描述了我应该期望的结果。

首先,请注意,它有一个,因此
KProperty1
的一个实例也可以用于
KProperty1
Baz
的超类型的地方,例如
Any

这正是使用不完全匹配的类型调用
eq
时发生的情况:使用更常见的超类型以便正确解析调用

例如,此呼叫:

Person::age eq 1.2f
实际上相当于:

Person::age.eq<Person, Any>(1.2f)
Person::年龄均衡(1.2f)
您甚至可以将其自动转换为这种形式,即使用普通调用替换中缀调用,然后添加显式类型参数

因此,每当类型不完全匹配时,就会为
R
选择一个公共超类型。目前,没有合适的方法告诉编译器它不应该返回到超类型(请参阅)

最后一个调用是类型推断当前工作方式的一个副作用:似乎编译器必须选择一个重载,然后才能决定它是否与nullability兼容。如果将
null
替换为
(null为字符串?
,则它可以工作。请将此问题提交到

一般来说,最好不要将通用签名与非通用签名混合使用,因为可能存在导致歧义的通用替换。在您的情况下,替换
R:=KProperty1
(即对这种类型的属性使用
eq
)将导致歧义

同样相关的还有:

  • (基本上是相同的情况,但这里对类型推断的工作原理有更详细的解释)