考虑这个有两个函数的类,一个带有Int
参数,另一个带有泛型函数:
class C<K, V> {
// ...
operator fun f(index: Int): Pair<K, V> = ...
operator fun f(key: K): V = ...
}
当参数化为C<Int, SomeType>
时,K
为Int
,并且两个函数都与调用匹配,从而导致错误:
val m = C<Int, SomeType>()
m.f(1)
重载分辨率模糊。所有这些功能都匹配:
{li>
public final fun f(index: Int): SomeType
在C
中定义 {li>public final fun f(key: Int): Pair<Int, SomeType>?
在C
中定义
在这种情况下如何拨打我想要的f
个?
答案 0 :(得分:9)
如果你有幸拥有这些功能的不同参数名称,那么使用named arguments就可以了:
m.f(index = 1) // calls f(index: Int)
m.f(key = 1) // calls f(key: K)
否则,如果参数名称相同(或在Java中定义),一种可能的解决方法是执行unchecked casts以使编译器选择所需的选项:
要致电f(index: Int)
,您可以使用
@Suppress("UNCHECKED_CAST")
val s = (m as C<*, SomeType>).f(1) as Pair<Int, SomeType>
转化为C<*, SomeType>
makes K
equivalent to in Nothing, out Any
,意味着f(key: K)
没有有效参数,因此调用自然会解析为f(index: Int)
,但您需要转换结果返回,因为否则它是Pair<Any, SomeType>
。
要致电f(key: K)
,请使用:
@Suppress("UNCHECKED_CAST")
val s = (m as C<Any, SomeType>).f(1 as Any)
同样,转化为C<Any, SomeType>
会将所需功能的签名更改为f(key: Any)
,并将其调用,只需将1
转换为Any
。
如果几个类型参数发生冲突(例如f(key: K)
和f(value: V)
K
和V
都是SomeType
),情况都是一样的,只需使用命名参数或将对象强制转换为禁止其中一个函数(in Nothing
)或使其接受Any
。
答案 1 :(得分:0)
Kotlin stdlib使用约定fun fAt(index: Int)
来解决此类问题。