类型的引用构造函数,不包括可选参数

时间:2018-02-03 18:17:20

标签: lambda constructor kotlin

我的类型为A,类型为contructor,需要参数x并且有一些可选参数:

class A(x: String, y: String = "default_y")

现在我想引用带有所需参数的构造函数:

var function: (String) -> A = ::A

现在我遇到了不兼容类型的问题,因为该构造函数的签名是2个字符串,而不仅仅是一个。

当我添加这个构造函数重载时,编译器停止抱怨:

class A(x: String, y: String = "default_y") {

constructor(x: String): this(x, "default_y")
}
//added just so you can see full code
var function: (String) -> A = ::A

我现在正在获得这种冗余。我当然可以做一些事情(将"default_y"提取为常量或从主构造函数中删除默认参数)以删除冗余,但这些只是糖代码并没有真正做任何事情。只是允许我引用它而不抱怨。 有没有办法引用构造函数(也可能是函数)作为只有必需参数的函数?

2 个答案:

答案 0 :(得分:1)

如上所述here以及here,您无法通过反思使用默认参数。

  

方法参数的默认值是一个任意表达式,只能表示为一个字节码块;没有其他可以用于反思的表示。参数信息通过解析源代码来检索默认参数值。

作为一种解决方法,您可以让编译器为您的构造函数生成JVM重载,然后使用Java反射来调用带有单个String参数的构造函数:

class A @JvmOverloads constructor(x: String, val y: String = "default_y")

val con: Constructor<A> = A::class.java.constructors
        .filterIsInstance<Constructor<A>>()
        .find { it.parameterCount == 1 } ?: throw IllegalStateException("Not found!")
val newInstance: A = con.newInstance("myArg")
println(newInstance.y) // Prints 'default_y'

编辑:

使用callBy,您还可以使用Kotlin反射调用构造函数:

val con = MyClass::class.constructors.first()
val newInst =
    con.callBy(mapOf(con.parameters.first() to "myArg"))

答案 1 :(得分:1)

虽然无法从签名中删除默认参数来获取函数引用,但您可以使用lambda而不是函数引用并调用仅提供所需参数的构造函数:

<section>