Order of init calls in Kotlin Array initialization

佐手、 提交于 2019-12-17 20:27:20

问题


In the constructor of an Array is there a guarantee that the init function will be called for the indexes in an increasing order?

It would make sense but I did not find any such information in the docs: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/-init-.html#kotlin.Array%24%28kotlin.Int%2C+kotlin.Function1%28%28kotlin.Int%2C+kotlin.Array.T%29%29%29%2Finit


回答1:


There is no guarantee for this in the API.

TLDR: If you need the sequential execution, because you have some state that changes see bottom.

First lets have a look at the implementations of the initializer:

Native: It is implemented in increasing order for Kotlin Native.

@InlineConstructor
public constructor(size: Int, init: (Int) -> Char): this(size) {
    for (i in 0..size - 1) {
        this[i] = init(i)
    }
}

JVM: Decompiling the Kotlin byte code for

class test {
    val intArray = IntArray(100) { it * 2 }
}

to Java in Android Studio yields:

public final class test {
   @NotNull
   private final int[] intArray;

   @NotNull
   public final int[] getIntArray() {
      return this.intArray;
   }

   public test() {
      int size$iv = 100;
      int[] result$iv = new int[size$iv];
      int i$iv = 0;

      for(int var4 = result$iv.length; i$iv < var4; ++i$iv) {
         int var6 = false;
         int var11 = i$iv * 2;
         result$iv[i$iv] = var11;
      }

      this.intArray = result$iv;
   }
}

which supports the claim that it is initialized in ascending order.

Conclusion: It commonly is implemented to be executed in ascending order.

BUT: You can not rely on the execution order, as the implementation is not guaranteed by the API. It can change and it can be different for different platforms (although both is unlikely).

Solution: You can initialize the array manually in a loop, then you have control about the execution order. The following example outlines a possible implementation that has a stable initialisation with random values, e.g. for tests.

val intArray = IntArray(100).also {
    val random = Random(0)
    for (index in it.indices) {
        it[index] = index * random.nextInt()
    }
}



回答2:


Starting from the version 1.3.50 Kotlin has guaranteed sequential array initialization order in its API documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/-init-.html

The function init is called for each array element sequentially starting from the first one. It should return the value for an array element given its index.



来源:https://stackoverflow.com/questions/56091276/order-of-init-calls-in-kotlin-array-initialization

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!