Order of init calls in Kotlin Array initialization

让人想犯罪 __ 提交于 2019-11-28 12:46:25
leonardkraemer

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