Kotlin:具有类型类型参数的通用函数,例如带有Object.type的Swift

时间:2018-11-09 13:42:31

标签: kotlin

我想创建一个带有接收类类型的参数的泛型函数,例如:

class Foo{
    var name = "Foooo"
}

class Liii{
    var name = "Liii"
}

通用函数:

fun genericFunc(objects: Any, objectType: KClass<*>) {
    print((objects as objectType).name) //This is not exist how to do this?
}

并这样称呼它:

val foo = Foo()
genericFun(foo, Foo::class)

val liii = Liii()
genericFun(liii, Liii::class)

它以这种方式迅速存在...

func genericFunc(objects: Any, objectType: Object.type) {
    print((objects as objectType).name)
}

let foo = Foo()
genericFun(foo, Foo.self)

1 个答案:

答案 0 :(得分:3)

首先,只有Class具有.name变量。老实说,我看不到您在这里做什么的意义。如果只需要名称,则可以直接执行objects::class.java.name。如果要使用KClass,则需要使用simpleNamequalifiedName。类还具有simpleNamepackageNametypeNamecanonicalName。这也意味着您需要上课。如果您绝对想投射它,则需要分别用KClassClass重新获得::class::class.java

另外,请注意:我不确定在Swift中打印的工作方式,但是在Kotlin和Java中,它不会打印新行。我之所以这样说是因为我知道Python之类的某些语言具有printSystem.out.println之类的println函数。但是,print不会自动创建换行符。


昨天我实际上偶然发现了这个确切的问题:如果我将KClass传递给函数,则无法传递whatever as kClass,因为找不到它。显然,您无法执行此操作。 asis采用类名,而不是ClassKClass的实例。

现在,您有两个选择,两个都使用泛型。

第一个仍在通过课程:

fun <T : Any> genericFunc(objects: Any, objectType: KClass<out T>) {
    println(objectType.java.cast(objects))

}

如果要打印名称,则必须获得我前面提到的类。这一点也没有意义,因为您可以执行以下操作:

println(objects::class.java.name) 

或者如果您绝对必须先进行转换(尽管我建议先使用isInstance进行检查):

println(objectType.java.cast(objects)::class.java.name)

但是,如果代码不是重点,那就继续吧。

另一种使用归一化类型。在这里您可以使用as

inline fun <reified T : Any> genericFunc(objects: Any) {
    print(objects as T)
}

最后一个叫法不同:

genericFunc<SomeClass>(instance);

但是; 这并不安全。我强烈建议您先检查类型。对于第一个,使用objectType.isInstance(objects),对于第二个,您可以仅使用is。否则,如果类型不匹配,则可能会遇到ClassCastException的风险。

此外,根据您打算对其进行处理,还可以完全使用泛型:

fun <T> genericFunc(objects: T) {
    // Do whatever
}

(可选)具有泛型类型的约束。