1

我有两种方法:

class Example {
    fun method(name: String): String {}

    fun method(name: String, length: Int): String {}
}

在我的代码中的某个时刻,我需要使用第二个版本的methodvia 反射,如下所示:

val func = Example::method

这无法编译,因为编译器无法区分此重载方法的两个定义之间的区别。我找不到指定函数参数的方法。文档说:

或者,您可以通过将方法引用存储在具有明确指定类型的变量中来提供必要的上下文:

val predicate: (String) -> Boolean = ::isOdd // refers to isOdd(x: String)

但在我的例子中,分配给的函数func可以是任意的,它不一定有两个类型的参数StringInt,在其他情况下,分配给这个属性的函数只有一个String参数。但在这种情况下,我需要带有两个参数的版本。

那么,有什么方法可以指定我正在使用哪个函数,如果没有,是否有任何解决方法?

4

1 回答 1

0

我认为反射的问题在于函数引用总是引用一个特定的函数。因此,在您的情况下,您需要 2 个函数引用来匹配以下两个版本method

val e = Example()
val func1: (String) -> String      = e::method 
val func2: (String, Int) -> String = e::method

这肯定不能满足你重载函数的需要,因为你要么必须使用func1要么func2分别

另一种方法是使用具有默认参数的函数而不是重载。此外,我将原始函数声明为私有并使用公共包装器来使两个函数仍然分开:

(当然你也可以只定义一个method带有可选参数的函数并在这个函数中区分):

class Example
{
    private fun method(name: String): String {
       return "Method1: $name"
    }

    private fun method(name: String, length: Int): String {
       return "Method2: $name ($length)"
    }

    fun method(name: String, length: Int? = null) : String {
        if (length == null)
           return method(name)
        else
           return method(name, length)
    }
} 

fun main(args: Array<String>) {
    val e = Example()
    
    // local function because lambda expression cannot have default parameters
    fun func (name: String, length: Int? = null): String {
        return e.method(name, length)
    }
    
    println(func("John"))
    println(func("Doe", 42))
}  
于 2020-07-24T13:07:59.380 回答