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

Lambda 类型为的引用构造函数,不包括可选参数,lambda,constructor,kotlin,Lambda,Constructor,Kotlin,我有一个A类型的类,它有构造函数,需要参数x,并且有一些可选参数: class A(x: String, y: String = "default_y") 现在我想用所需的参数引用构造函数: class A(x: String, y: String = "default_y") var函数:(字符串)->A=::A 现在我遇到了不兼容类型的问题,因为构造函数的签名是2个字符串,而不仅仅是一个 当我添加此构造函数重载时,编译器停止抱怨: class A(x: String, y: String

我有一个
A
类型的类,它有构造函数,需要参数
x
,并且有一些可选参数:

class A(x: String, y: String = "default_y")
现在我想用所需的参数引用构造函数:

class A(x: String, y: String = "default_y")
var函数:(字符串)->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”
提取为常量或从主构造函数中删除默认参数)来消除冗余,但这一切都只是糖类代码,并没有真正起到任何作用。只允许我毫无怨言地引用它。 是否有方法引用构造函数(可能还有函数)以及只使用必需参数的函数?

如上所述,而且,您不能通过反射使用默认参数

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

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

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'
val function: (String) -> A = { A(it) } // uses the default for `y`

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

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'
val function: (String) -> A = { A(it) } // uses the default for `y`

严格来说,我不是在说反思。我的代码是独立于平台的(使用新的多平台功能),所以我不能使用
@JvmOverloads
,它在javascript中也不能工作。但是谢谢你的回答,它清除了一些。我不确定它在这里是否相关,但事实上你可以通过Kotlin反射使用默认参数:通过,你可以省略映射中参数的一个条目来使用默认参数。这似乎也适用于Kotlin/JS。