Kotlin의 IntArray 대 Array <Int>


91

Kotlin에서 an IntArray과 an 의 차이점이 무엇인지, Array<Int>왜 서로 바꿔서 사용할 수 없는지 잘 모르겠습니다.

미스 매치

를 타겟팅 IntArrayint[]때로 번역 된다는 것을 알고 JVM있지만 무엇으로 Array<Int>번역 되나요?

또한 String[]또는 YourObject[]. {primitive}Array프리미티브뿐만 아니라 거의 모든 것이 배열에 배열 될 수 있는데 Kotlin에 유형의 클래스가있는 이유 입니다.


1
생각 엔 그입니다 Array<Int>에 컴파일 Integer[](컴파일러가이 최적화되어 있지 않은 경우)
MIBAC


네, 말이됩니다. 둘 다 감사합니다!
FRR

답변:


111

Array<Int>이다 Integer[]하면서 후드 IntArray이다 int[]. 그게 다야.

당신이를 넣을 때이 수단 IntArray<Int>, 항상 (AN으로, 특히 박스됩니다 Integer.valueOf()호출). 의 경우 IntArrayJava 기본 배열로 변환되므로 boxing이 발생하지 않습니다.


위의 가능한 성능 영향 외에도 고려할 편의성도 있습니다. 기본 배열은 초기화되지 않은 상태로 둘 수 있으며 0모든 인덱스에 기본값이 있습니다 . 이것이 바로 IntArray나머지 기본 배열에 크기 매개 변수 만 취하는 생성자 가있는 이유입니다 .

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

반대로, Array<T>크기 매개 변수 만 취하는 생성자는 없습니다 T. 생성 후 유효한 상태가 되려면 모든 인덱스에서 null이 아닌 유효한 인스턴스가 필요합니다 . 위해 Number유형이 기본이 될 수 0있지만, 임의의 유형의 기본 인스턴스를 생성 할 수있는 방법이 없습니다 T.

따라서를 만들 때 Array<Int>초기화 함수를 사용하는 생성자를 사용할 수도 있습니다.

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

또는 Array<Int?>모든 값을 초기화 할 필요가 없도록를 만들지 만 나중에 null배열에서 읽을 때마다 가능한 값 을 처리해야합니다 .

val arr = arrayOfNulls<Int>(10)

4
이것은 아주 어리석은 결정입니다. 이 때문에 각 기본 유형에 대해 새 클래스를 만들어야했습니다 ... Java에서와 동일하게 사용할 수 있습니다.
안드로이드 개발자

1
@androiddeveloper 어떤 새로운 클래스? int[]이다 IntArray, Integer[]이다 Array<Int>, 등등, 어디에서이 신비한 새로운 클래스입니까? 구문이 다른 것과 같은 것입니다. int[]그건 그렇고 클래스이기도합니다.
Eugen Pechanec

1
@EugenPechanec 이것은 흥미 롭습니다. 그들은 그것이 클래스이고 인스턴스가 있다고 말하지만 "이 클래스의 인스턴스는 int []"로 표현됩니다 : kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int-array/… . 그렇다면 이러한 함수는 확장 함수일까요 아니면 실제 클래스일까요? 그리고 왜 "IntArray"와 다른 것이 필요했을까요? 여전히 Java 구문을 사용하여 수행 할 수 있습니다.
안드로이드 개발자

1
@EugenPechanec하지만 Java에서 int []는 클래스가 아닙니다. 그것은 객체, 원시의 배열입니다. 코드에 도달하거나 확장 할 수 없습니다. 아니? Java의 모든 클래스에는 이름에 대문자가 있습니다. 여기 없습니다.
안드로이드 개발자

1
@EugenPechanec 그래서 Kotlin에서는 클래스이고 Java에서는 그렇지 않습니다. 그래도 이유를 모르겠습니다. 그들은 단지 확장 기능을 추가 할 수 있습니다. IntArray에서 확장 할 수 있습니까? 명명에 대해 알고 있습니다. 그것은 단지 컨벤션이고 좋은 것이기도합니다.
안드로이드 개발자

6

*a에 spread ( ) 연산자 를 사용 vararg하면 IntArray. 필요한 경우를 사용하여 Array<Int>변환 할 수 있습니다 .IntArray.toTypedArray()


1

Kotlin의 배열은 클래스입니다 (자바와 같은 '특수'유형이 아님).

Kotlin의 stdlib는 Java 언어 통합 및 성능을 개선하기 위해 JVM 기본 배열을위한 특수 목적 클래스를 제공합니다.

경험상의 규칙은 Array<T>기존 Java 코드와 혼합 할 때 문제가 발생하거나 Java 클래스에서 호출되어야하는 경우를 제외하고 는 사용하는 것입니다. 기록을 위해 IntArray.

이 문제에 관한 언어 문서는 https://kotlinlang.org/docs/reference/basic-types.html#arrays 에서 확인할 수 있습니다.


IntArray보다 Array <T>를 항상 선호하는 것이 옳다고 생각합니다. boxed type과 primitive를 사용하는 데 따른 boxing / unboxing 오버 헤드에 대해 걱정했지만 Kotlin은 기본 요소를 사용할 수 있는지 여부를 결정할만큼 똑똑한 것 같습니다. . (내가 틀렸다면 고쳐주세요) "Java 플랫폼에서는 nullable 숫자 참조 (예 : Int?)가 필요하지 않거나 제네릭이 관련되지 않는 한, 숫자가 JVM 기본 유형으로 물리적으로 저장됩니다. 후자의 경우 숫자가 박스형입니다." 에서 kotlinlang.org/docs/reference/basic-types.html
FRR

@feresr하지 않은 수단을 통해 전문가,하지만 난 그 단지의 구현을 참조 생각 Int, Float코 틀린를위한 다른 유형이 없음을 주어, 등, Boolean또는 boolean. 배열 측면 Array<Int>에서 IntArray. 저는 개인적으로 항상 후자를 사용해 왔는데, 결코 신경 쓰지 않았기 때문에 Kotlin에 제가 알지 못하는 추가 최적화가있을 수 있습니다. kotlin으로 만 프로그래밍하는 경우 다른 것보다 하나 가 필요한 경우는 없지만 기본 배열에는 여전히 이점이있을 수 있습니다.
Allan W

@AllanW는 전문가가 아닙니다. 호기심이 많습니다 .Java는 기본 요소로 작업하는 것이 더 효율적이기 때문에 기본 요소와 박스형 개체를 모두 가지고 있다고 생각합니다. 물론 때로는 실제로 개체 (널 가능성 / 제네릭)로 작업해야합니다. 이것은 내 원래 질문의 범위를 벗어나지 만 Kotlin이 JVM을 대상으로 할 때 어떻게 처리하는지 궁금합니다. 가능할 때마다 IntArray를 사용하려고하지만 (내부에서 기본 요소를 사용하고 있다고 생각) @ 재밍 주석 후에는 더 이상 확실하지 않습니다.
FRR

1
@feresr, Kotlin의 문서는 복싱 오버 헤드를 피하기 위해 특수 배열 인스턴스가 있음을 명시 적으로 설명합니다. 필자의 요점은 두 가지가 다를 수 있으며 결국 개발자에게 Java에서 Integer [] 또는 int []를 사용할지 여부를 결정하는 것과 같습니다.
Allan W

동의합니다. 그러면 수락 된 답변이 신규 이민자에게 약간의 오해의 소지가있을 수 있습니다. 이러한 이유로 수락 된 답변으로 표시를 해제하겠습니다.
FRR
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.