替代函数重载

时间:2018-01-08 05:19:19

标签: kotlin overloading

以下代码

fun getValue(): Int {
   return 42
}

fun getValue(): String {
   return "Foo"
}

给出以下错误:

  

冲突重载:local final fun getValue():在中定义的字符串   main,local final fun getValue():在main中定义的Int。

有没有办法解决这个问题而不重命名其中一个功能?

4 个答案:

答案 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"

但是,这仍然无法解决您的问题。由于您没有向我们提供任何信息为什么您需要这样的声明,我只能给您一些建议:

  1. value以外的两个变量找到更有意义的名称。例如:

    val intValue get() = 42 // note that you can omit :Int in this case
    val textValue get() = "Foo"
    
  2. 如果两个值绑定在一起,则可以使用Pair

    val value get() = 42 to "Foo"
    

    现在,您可以通过value.firstvalue.second访问这两个值。请注意,toinfix function,可创建Pair,因此上述内容相当于更详细的符号

    val value : Pair<Int, String> get() = Pair(42, "Foo")
    
  3. 如果value值得存储在自己的对象中而不是使用Pair,那么您可以为它创建自己的数据类:

    data class MyData(val intVal : Int, val textVal : Text)
    val value get() = MyData(42, "Foo")
    
  4. 使用解决方案 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。