Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 有没有办法从';字符串';至';KType';?_Kotlin - Fatal编程技术网

Kotlin 有没有办法从';字符串';至';KType';?

Kotlin 有没有办法从';字符串';至';KType';?,kotlin,Kotlin,简单地说,我想要一个如下的函数: fun <T> convert(val foo: String, fooT: KType) : T { ...? } fun转换(val-foo:String,fooT:KType):T{ ...? } 对于Int,它将返回foo.toInt(),对于Double,foo.toDouble(),对于某些未知类型,只会抛出异常。我认为为我所期望的类型创建自己的switch语句并不难,但出于好奇,是否已经有了一种方法?推荐的方法 不幸的是,没

简单地说,我想要一个如下的函数:

fun <T> convert(val foo: String, fooT: KType) : T {
    ...?
}
fun转换(val-foo:String,fooT:KType):T{
...?
}
对于
Int
,它将返回
foo.toInt()
,对于
Double
foo.toDouble()
,对于某些未知类型,只会抛出异常。我认为为我所期望的类型创建自己的switch语句并不难,但出于好奇,是否已经有了一种方法?

推荐的方法 不幸的是,没有简单的泛型方法,因为我们不处理强制转换,而是处理方法调用。这就是我的方法:

fun <T> convert(str: String, type: KType) : T {

    val result: Any = when (type.jvmErasure)
    {
        Long::class -> str.toLong()
        Int::class -> str.toInt()
        Short::class -> str.toShort()
        Byte::class -> str.toByte()
        ...
        else -> throw IllegalArgumentException("'$str' cannot be converted to $type")
    }

    return result as T // unchecked cast, but we know better than compiler
}

非常好-第一个是我现在实际正在做的事情(尽管我只是让它返回
Any
,而不是让调用方指定类型)。我在
convert
的调用者中使用反射-基本上是从API调用中获取结果,并基于对象构造函数中的类型构造对象,但我认为没有什么依赖于实现细节。
@UseExperimental(ExperimentalStdlibApi::class)
fun main() {

    val int = convert<Int>("32", typeOf<Int>())

    println("converted: $int")
}
fun convert(str: String, type: KType): Any {
    val conversionClass = Class.forName("kotlin.text.StringsKt") 
    // here, the to*OrNull() methods are stored
    // we effectively look for static method StringsKt.to*OrNull(String)

    val typeName = type.jvmErasure.simpleName
    val funcName = "to${typeName}OrNull" // those are not inline

    val func = try {
        conversionClass.getMethod(funcName, String::class.java) // Java lookup
    } catch (e: NoSuchMethodException) {
        throw IllegalArgumentException("Type $type is not a valid string conversion target")
    }

    func.isAccessible = true      // make sure we can call it
    return func.invoke(null, str) // call it (null -> static method)
            ?: throw IllegalArgumentException("'$str' cannot be parsed to type $type")
}