Kotlin'de IntArray vs Array <Int>


91

Kotlin'de an IntArrayve an arasındaki farkın ne olduğundan Array<Int>ve neden onları birbirinin yerine kullanamadığımdan emin değilim :

yanlış eşleşme

Bunu hedeflerken bunun IntArraytercüme int[]edildiğini biliyorum JVM, ama ne anlama Array<Int>geliyor?

Ayrıca String[]veya olabilir YourObject[]. Neden Kotlin'in {primitive}Arraysadece ilkeller değil, hemen hemen her şey bir dizi halinde düzenlenebildiği halde bu tür sınıflar var .


1
Benim tahminim olmasıdır Array<Int>için derler Integer[](derleyici bu duruma yoksa)
MiBAC


Evet, bu çok mantıklı, ikinize de teşekkürler!
FRR

Yanıtlar:


111

Array<Int>bir bir Integer[]ise, başlık altında IntArraybir bir int[]. Bu kadar.

Bu Int, bir içine bir koyduğunuzda Array<Int>, her zaman kutulu olacağı anlamına gelir (özellikle, bir Integer.valueOf()çağrı ile). Böyle bir durumda, IntArraybir Java ilkel dizisine çevrildiği için kutulama gerçekleşmez.


Yukarıdakilerin olası performans etkileri dışında, dikkate alınması gereken kolaylıklar da vardır. İlkel diziler başlatılmadan bırakılabilir ve 0tüm dizinlerde varsayılan değerlere sahip olurlar . Bu nedenle IntArray, ilkel dizilerin geri kalanının yalnızca bir boyut parametresi alan yapıcıları vardır:

val arr = IntArray(10)
println(arr.joinToString()) // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

Bunun aksine, Array<T>yalnızca boyut parametresi alan bir kurucuya sahip değildir: Toluşturulduktan sonra geçerli bir durumda olması için tüm dizinlerde geçerli, boş olmayan örneklere ihtiyaç duyar . Türler için Numberbu bir varsayılan olabilir 0, ancak rastgele bir türün varsayılan örneklerini oluşturmanın bir yolu yoktur T.

Yani bir oluştururken Array<Int>, bir başlatıcı işlevi de alan yapıcıyı kullanabilirsiniz:

val arr = Array<Int>(10) { index -> 0 }  // full, verbose syntax
val arr = Array(10) { 0 }                // concise version

Veya Array<Int?>her değeri başlatmak zorunda kalmamak için bir tane oluşturun , ancak daha sonra nulldiziden her okuduğunuzda olası değerlerle uğraşmaya zorlanacaksınız .

val arr = arrayOfNulls<Int>(10)

4
Bu oldukça aptalca bir karar. Bu nedenle, her ilkel tür için yeni bir sınıf oluşturmaları gerekiyordu ... Java'dakiyle aynı şeyi kullanabilirlerdi.
android geliştiricisi

1
@androiddeveloper Hangi yeni sınıf? int[]olduğu IntArray, Integer[]olduğu Array<Int>, ve benzeri, nerede bu gizemli yeni sınıf var? Aynı şey, sadece sözdizimi farklıdır. int[]bu arada, aynı zamanda sınıftır.
Eugen Pechanec

1
@EugenPechanec Bu ilginç. Bunun bir sınıf olduğunu ve bir örneği olduğunu söylüyorlar, ama aynı zamanda "bu sınıfın örnekleri int [] olarak temsil ediliyor": kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int-array/… . Öyleyse, bu işlevler yalnızca uzantı işlevleri mi yoksa gerçek bir sınıftan mı? Ve neden "IntArray" ve diğerlerine sahip olmak gerekiyordu? Yine de Java sözdizimi kullanılarak yapılabilir.
android geliştiricisi

1
@EugenPechanec Ama Java'da int [] bir sınıf değil, değil mi? Bu bir nesne, bir dizi ilkel. Ulaşamazsınız koddur veya ondan uzanamazsınız. Hayır? Java'daki tüm sınıfların adlarında büyük harf vardır. Burada değil.
android geliştiricisi

1
@EugenPechanec Yani Kotlin'de bu bir sınıf, Java'da değil. Yine de nedenini anlamadım. Sadece uzantı işlevleri ekleyebilirler, değil mi? Belki IntArray'den uzatabilirsiniz? Adlandırma hakkında biliyorum. Bu sadece bir kongre ve aynı zamanda iyi bir kongre.
android geliştiricisi

6

A *üzerinde spread ( ) operatörünün kullanılmasının varargbir IntArray. Bir ihtiyacınız varsa Array<Int>, IntArraykullanarak dönüştürebilirsiniz .toTypedArray().


1

Kotlin'deki diziler sınıflardır (Java gibi "özel" türler değildir).

Kotlin'in stdlib'i, Java dil entegrasyonunu ve performansını geliştirmek için JVM ilkel dizileri için özel amaçlı sınıflar sağlar.

Temel kural, Array<T>mevcut Java koduyla karıştırırken bir soruna neden olmaması veya Java sınıflarından çağrılması dışında kullanılması olacaktır. Kayıt için hiç kullanmak zorunda kalmadım IntArray.

Bu konuyla ilgili Dil belgelerine buradan bakabilirsiniz: https://kotlinlang.org/docs/reference/basic-types.html#arrays


Her zaman Array <T> 'yi IntArray yerine tercih etme konusunda haklı olduğunuza inanıyorum, kutulu türü kullanmanın kutulu / kutudan çıkarılmış ek yükünden ilkel olana karşı endişeliydim, ancak Kotlin ilkel olanı kullanıp kullanmayacağına karar verecek kadar akıllı . (Yanılıyorsam düzeltin) "Java platformunda, boş bir sayı referansına (örn. Int?) Veya jeneriklere ihtiyacımız olmadığı sürece, sayılar fiziksel olarak JVM ilkel türler olarak depolanır. İkinci durumlarda sayılar kutu içine alınır." Kotlinlang.org/docs/reference/basic-types.html
FRR

@feresr değil herhangi bir yöntemle uzman, ama bu sadece uygulamaların atıfta düşünüyorum Int, FloatKotlin için farklı bir türü yok olduğu göz önüne alındığında, vs, Booleanveya boolean. Diziler açısından Array<Int>bunun farklı olacağını varsayıyorum IntArray. Beni hiç rahatsız etmediği için kişisel olarak her zaman ikincisini kullandım, ancak Kotlin'in farkında olmadığım ek optimizasyonları olabilir. Yalnızca kotlin'de programlama yapıyorsanız, birine diğerinin üzerine ihtiyaç duyduğunuz herhangi bir durum görmüyorum , ancak ilkel dizinin yine de faydaları olabilir.
Allan W

@AllanW da bir uzman değil, sadece merak ediyorum, java'nın hem ilkellere hem de kutulu nesnelere sahip olduğuna inanıyorum çünkü ilkellerle çalışmak daha verimli değil mi? Elbette bazen gerçekten nesneyle çalışmanız gerekir (sıfırlanabilirlik / jenerik). Bu, asıl sorumun kapsamı dışında kalıyor ama Kotlin'in JVM'yi hedeflerken bunu nasıl ele aldığını merak ediyorum. Mümkün olduğunca IntArray'i kullanmaya çalışıyorum (başlık altında ilkelleri kullandığını düşünüyorum) ama @ jamming yorumundan sonra artık emin değilim.
FRR

1
Bana @feresr, Kotlin'in dokümanları, özel dizi örneklerinin boks yükünden kaçınmak için orada olduğunu açıkça belirtiyor. Benim çıkarım, bu ikisinin muhtemelen farklı olması ve sonunda geliştiricinin Java'da Tamsayı [] veya int [] kullanmak isteyip istemediğinize karar vermekle aynı hale gelmesi.
Allan W

Kabul ediyorum, o zaman kabul edilen cevap yeni gelenler için biraz yanıltıcı olabilir, bu nedenle kabul edilen cevap olarak bunun işaretini kaldırıyorum.
FRR
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.