Kotlin 数组的具体化内联函数
在Kotlin中是否可以编写一个具有具体化类型的内联函数,该函数可以返回不同类型的Kotlin 数组的具体化内联函数,kotlin,Kotlin,在Kotlin中是否可以编写一个具有具体化类型的内联函数,该函数可以返回不同类型的数组?我会这样想: inline fun <reified E> getArray(key: String, defValue: Array<E>): Array<E>? { return when(defValue) { is Array<Int> -> // ... is Array<String?> -&
数组
?我会这样想:
inline fun <reified E> getArray(key: String, defValue: Array<E>): Array<E>? {
return when(defValue) {
is Array<Int> -> // ...
is Array<String?> -> // ...
else // ...
}
}
fun intArray(size: Int): Array<Int> = Array(size) {i -> 0}
fun stringArray(size: Int): Array<String?> = Array(size) {i -> null}
val strings: Array<Int> = getArray(KEY_INTS, intArray(0))
val strings: Array<String> = getArray(KEY_STRINGS, stringArray(0))
inline-fun-getArray(key:String,defValue:Array):数组?{
返回时间(defValue){
是数组->/。。。
是数组->/。。。
else/。。。
}
}
我想这样称呼它:
inline fun <reified E> getArray(key: String, defValue: Array<E>): Array<E>? {
return when(defValue) {
is Array<Int> -> // ...
is Array<String?> -> // ...
else // ...
}
}
fun intArray(size: Int): Array<Int> = Array(size) {i -> 0}
fun stringArray(size: Int): Array<String?> = Array(size) {i -> null}
val strings: Array<Int> = getArray(KEY_INTS, intArray(0))
val strings: Array<String> = getArray(KEY_STRINGS, stringArray(0))
fun intArray(size:Int):数组=数组(size){i->0}
数组(大小:Int):数组=数组(大小){i->null}
val strings:Array=getArray(KEY_INTS,intArray(0))
val strings:Array=getArray(KEY_strings,stringArray(0))
但由此我得到了一个错误:
找不到已擦除类型的实例的检查
明确回答问题-您可以通过检查
E
类来使用它:
inline fun <reified E: Any> getArrayInline(key: String, defValue: Array<E>): Array<E>? {
return when(E::class) {
Int::class -> arrayOf(1, 2, 3)
String::class -> arrayOf("a", "b", "c")
else -> throw IllegalArgumentException("Invalid class: ${E::class.qualifiedName}")
} as Array<E>
}
简单对吧?但一旦你查看生成的字节码,它就不那么好了。为了便于阅读,将Kotlin字节码反编译回Java:
public static final void testArrayInline() {
String var1 = "key";
Object[] defValue$iv = new Integer[0];
KClass var3 = Reflection.getOrCreateKotlinClass(Integer.class);
Object var10000;
if (Intrinsics.areEqual(var3, Reflection.getOrCreateKotlinClass(Integer.TYPE))) {
var10000 = new Integer[]{1, 2, 3};
} else {
if (!Intrinsics.areEqual(var3, Reflection.getOrCreateKotlinClass(String.class))) {
throw (Throwable)(new IllegalArgumentException("Invalid class: " + Reflection.getOrCreateKotlinClass(Integer.class).getQualifiedName()));
}
var10000 = new String[]{"a", "b", "c"};
}
Integer[] test = (Integer[])((Object[])var10000);
String var7 = "key2";
Object[] defValue$iv = new String[0];
KClass var4 = Reflection.getOrCreateKotlinClass(String.class);
if (Intrinsics.areEqual(var4, Reflection.getOrCreateKotlinClass(Integer.TYPE))) {
var10000 = new Integer[]{1, 2, 3};
} else {
if (!Intrinsics.areEqual(var4, Reflection.getOrCreateKotlinClass(String.class))) {
throw (Throwable)(new IllegalArgumentException("Invalid class: " + Reflection.getOrCreateKotlinClass(String.class).getQualifiedName()));
}
var10000 = new String[]{"a", "b", "c"};
}
String[] test2 = (String[])((Object[])var10000);
}
考虑到函数只被调用了两次,在“when”块中有两个案例,它是相当大的。而且它甚至没有做任何有用的事情-您已经可以看到if
案例的结果
正确的方法-将每种类型声明为单独的非内联函数:
fun getArray(key: String, defValue: Array<Int>) : Array<Int>{
return arrayOf(1, 2, 3)
}
fun getArray(key: String, defValue: Array<String>) : Array<String>{
return arrayOf("a", "b", "c")
}
public static final void testArray() {
String var3 = "key";
Integer[] var4 = new Integer[0];
getArray(var3, var4);
var3 = "key2";
String[] var5 = new String[0];
getArray(var3, var5);
}
明确回答问题-您可以通过检查
E
类来使用它:
inline fun <reified E: Any> getArrayInline(key: String, defValue: Array<E>): Array<E>? {
return when(E::class) {
Int::class -> arrayOf(1, 2, 3)
String::class -> arrayOf("a", "b", "c")
else -> throw IllegalArgumentException("Invalid class: ${E::class.qualifiedName}")
} as Array<E>
}
简单对吧?但一旦你查看生成的字节码,它就不那么好了。为了便于阅读,将Kotlin字节码反编译回Java:
public static final void testArrayInline() {
String var1 = "key";
Object[] defValue$iv = new Integer[0];
KClass var3 = Reflection.getOrCreateKotlinClass(Integer.class);
Object var10000;
if (Intrinsics.areEqual(var3, Reflection.getOrCreateKotlinClass(Integer.TYPE))) {
var10000 = new Integer[]{1, 2, 3};
} else {
if (!Intrinsics.areEqual(var3, Reflection.getOrCreateKotlinClass(String.class))) {
throw (Throwable)(new IllegalArgumentException("Invalid class: " + Reflection.getOrCreateKotlinClass(Integer.class).getQualifiedName()));
}
var10000 = new String[]{"a", "b", "c"};
}
Integer[] test = (Integer[])((Object[])var10000);
String var7 = "key2";
Object[] defValue$iv = new String[0];
KClass var4 = Reflection.getOrCreateKotlinClass(String.class);
if (Intrinsics.areEqual(var4, Reflection.getOrCreateKotlinClass(Integer.TYPE))) {
var10000 = new Integer[]{1, 2, 3};
} else {
if (!Intrinsics.areEqual(var4, Reflection.getOrCreateKotlinClass(String.class))) {
throw (Throwable)(new IllegalArgumentException("Invalid class: " + Reflection.getOrCreateKotlinClass(String.class).getQualifiedName()));
}
var10000 = new String[]{"a", "b", "c"};
}
String[] test2 = (String[])((Object[])var10000);
}
考虑到函数只被调用了两次,在“when”块中有两个案例,它是相当大的。而且它甚至没有做任何有用的事情-您已经可以看到if
案例的结果
正确的方法-将每种类型声明为单独的非内联函数:
fun getArray(key: String, defValue: Array<Int>) : Array<Int>{
return arrayOf(1, 2, 3)
}
fun getArray(key: String, defValue: Array<String>) : Array<String>{
return arrayOf("a", "b", "c")
}
public static final void testArray() {
String var3 = "key";
Integer[] var4 = new Integer[0];
getArray(var3, var4);
var3 = "key2";
String[] var5 = new String[0];
getArray(var3, var5);
}
如果处理的类型有限,则应该考虑将该方法拆分为具有不同返回类型的倍数。内联巨大的switch语句会生成大量垃圾字节码。由于数组元素类型为E,因此可以检查类型E::class,而不是defValue@ErwinBolwidt你是说像E::class==Int::class之类的东西,或者我应该怎么做?你能详细解释一下吗?对不起,我是Kotlin新手,在java的限制下仍在思考……如果您处理的类型有限,您应该考虑将此方法分割成具有不同返回类型的倍数。内联巨大的switch语句会生成大量垃圾字节码。由于数组元素类型为E,因此可以检查类型E::class,而不是defValue@ErwinBolwidt你是说像E::class==Int::class之类的东西,或者我应该怎么做?你能详细解释一下吗?很抱歉,我是Kotlin的新手,仍然在思考Java的局限性……感谢您的回答。如果要使
defValue
参数为空,您有什么建议?如果我调用getArray(“…”,null)
它将导致重载解析歧义。那么我真的必须使用不同的方法名吗?@Cilenconull
在这种情况下是不明确的,编译器无法解析要调用哪个方法。您必须将其强制转换为所需的可空类型,例如getArray(“…”,null as Array?
。感谢您的回答。如果要使defValue
参数为空,您有什么建议?如果我调用getArray(“…”,null)
它将导致重载解析歧义。那么我真的必须使用不同的方法名吗?@Cilenconull
在这种情况下是不明确的,编译器无法解析要调用哪个方法。您必须将其强制转换为所需的可空类型,例如getArray(“…”,null as Array?
。