以下代码
fun getValue(): Int {
return 42
}
fun getValue(): String {
return "Foo"
}
给出以下错误:
冲突重载:local final fun getValue():在中定义的字符串 main,local final fun getValue():在main中定义的Int。
有没有办法解决这个问题而不重命名其中一个功能?
答案 0 :(得分:2)
inline fun <reified T> getValue(): T =
when (T::class) {
Int::class -> 42 as T
String::class -> "foo" as T
else -> throw IllegalArgumentException()
}
您可以使用带有reified类型参数的通用内联函数。 每个调用都会内联给定的代码块。
缺点是编译器无法检查错误的类型参数。您将获得IllegalArgumentException
。
答案 1 :(得分:2)
首先,不鼓励在Kotlin中编写显式getter,建议使用以下代码:
val value : Int get() = 42
val value : String get() = "Foo"
但是,这仍然无法解决您的问题。由于您没有向我们提供任何信息为什么您需要这样的声明,我只能给您一些建议:
为value
以外的两个变量找到更有意义的名称。例如:
val intValue get() = 42 // note that you can omit :Int in this case
val textValue get() = "Foo"
如果两个值绑定在一起,则可以使用Pair
:
val value get() = 42 to "Foo"
现在,您可以通过value.first
和value.second
访问这两个值。请注意,to
是infix function,可创建Pair
,因此上述内容相当于更详细的符号
val value : Pair<Int, String> get() = Pair(42, "Foo")
如果value
值得存储在自己的对象中而不是使用Pair
,那么您可以为它创建自己的数据类:
data class MyData(val intVal : Int, val textVal : Text)
val value get() = MyData(42, "Foo")
使用解决方案 2 和 3 ,可以使用destructuring declaration,如下所示:
val (intVal, textVal) = value
答案 2 :(得分:2)
简答:否。
Long anser:函数签名由该函数的名称及其参数列表组成。
由于返回类型不属于签名,因此编译器无法区分调用时使用的函数:
val v = getValue() // should v be inferred to Int or String?
甚至没有明确指定返回类型解决问题:
val v: Int = getValue()
因为首先评估getValue()
而不“知道”将指定返回值的位置。
因此,您最好的选择是为其中一个功能选择不同的名称。
答案 3 :(得分:1)
客户应该如何指定他实际想要从您的班级实例中获取哪个值?这些方法名称含糊不清。
查看方法签名,只有返回类型不同,这是不够的。
Java的重载方法的规则也适用于Kotlin:
重载方法通过传递给方法的参数的数量和类型来区分。
在您的情况下,只需提供适当的可区分名称。如果你的类,你也可以简单地创建那些值属性,不需要显式定义默认的getter。