부호 없는 정수
정수형 타입에 더해, Kotlin 은 아래에 기술된 부호 없는 정수 타입도 제공합니다:
타입 | 크기(bits) | 최소값 | 최대값 |
---|---|---|---|
UByte | 8 | 0 | 255 |
UShort | 16 | 0 | 65353 |
UInt | 32 | 0 | 4,294,967,295 (232 - 1) |
ULong | 64 | 0 | 18,446,744,073,709,551,615 (264 - 1) |
부호 없는 타입은 부호가 있는 그것들에 존재하던 대부분의 연산을 지원합니다.
부호없는 정수는 같은 너비를 가지는 부호가 붙은 타입 하나를 저장하는 인라인 클래스 로 구현되어있습니다. 어떤 변수의 타입을 부호가 있는 것에서 그렇지 않은 것으로, 혹은 그 반대로 변경하려 한다면, 그 변수를 사용하는 모든 연산 작업이 새로운 타입에서 지원되는지 확인해야합니다.
부호없는 정수의 배열과 범위
부호없는 배열과 그들에 대한 연산은 아직 Beta 단계에 있습니다. 이들은 언제든지 이전과 호환되지 않는 형태로 변경될 수 있기 때문에 명시적인 Opt-in 을 필요로 합니다(아래에 기술된 자세한 사항을 확인해주세요).
원시 타입들과 동일하게, 부호가 없는 타입들도 그들 각각에 대응하는 배열 타입을 가지고 있습니다:
UByteArray
: 부호 없는 Byte 들의 배열UShortArray
: 부호 없는 Short 들의 배열UIntArray
: 부호 없는 Int 들의 배열ULongArray
: 부호 없는 Long 들의 배열
부호가 있는 정수의 배열들과 동일하게, Array
가 제공하는 것들과 비슷한 API 를 별도의 오버헤드 없이 제공합니다.
부호가 없는 정수의 배열을 사용할 때, 이들이 아직 안정적이지 않다는 경고와 마주치게 될 것입니다.
이 경고를 지우려면, @ExperimentalUnsignedTypes
어노테이션을 사용하여 opt-in 하세요.
이는 당신의 API 사용자에게 명시적으로 opt-in 을 하게 함으로써, 이 API는 아직 안정적이지 않은 부호 없는 정수의 배열을 사용하며 언제든 동작이 망가질 수 있음을 인지하게 합니다.
이 문서에서 opt-in 필요사항에 대해 더 알아보세요.
범위와 수열들은 UInt
와 ULong
에 대해 UIntRange
, UIntProgression
, ULongRange
, ULongProgression
으로 지원됩니다.
부호 없는 정수형 타입들과 동일하게, 이들은 안정적입니다.
부호 없는 정수의 리터럴
부호 없는 정수를 더 쉽게 사용하기 위해, Kotlin 에서는 정수 리터럴의 끝에 특정 정수 타입의 부호가 없음을 나타내는 접미사를 붙힐 수 있습니다(Float
나 Long
과 비슷하게요):
u
와U
는 부호 없는 정수의 리터럴을 위한 접미사입니다. 실제 타입은 선언에 명시된 타입을 따르며, 그것이 없으면 컴파일러가 리터럴의 크기에 따라UInt
나ULong
을 사용합니다.1val b: UByte = 1u // UByte, 명시된 타입 2val s: UShort = 1u // UShort, 명시된 타입 3val l: ULong = 1u // ULong, 명시된 타입 4 5val a1 = 42u // UInt, 타입이 제공되지 않았으며 값이 UInt 범위 내에 있습니다. 6val a2 = 0xFFFF_FFFF_FFFFu // ULong, 타입이 제공되지 않았으며 값이 UInt 범위 밖에 있습니다. 7
uL
과UL
은 부호 없는 Long 타입을 표현할 때 사용합니다.1val a = 1UL // 타입이 제공되지 않았으며 값이 UInt 범위 내에 있음에도 ULong 입니다. 2
사용 케이스
부호 없는 숫자들의 주된 사용 케이스는 전체 비트열을 모두 사용하여 이 값이 양수임을 나타내야할 때입니다.
예를 들어, 32비트 AARRGGBB
포멧의 색상을 표현하기 위한 16진수의 상수는 부호가 있는 타입의 범위 안에 있지 않기 때문에, 이런 케이스에 적합합니다:
1data class Color(val representation: UInt)
2
3val yellow = Color(0xFFCC00CCu)
4
부호 없는 정수를 toByte()
라는 명시적 캐스팅 없이 Byte 배열을 초기화하기 위해서 사용할 수도 있습니다:
1val byteOrderMarkUtf8 = ubyteArrayOf(0xEFu, 0xBBu, 0xBFu)
2
또 다른 케이스는 네이티브 API 들과의 상호 운용성이 필요할 때입니다. Kotlin 은 시그니쳐에 부호 없는 타입을 포함하는 네이티브 코드 정의의 표현을 허용하며, 시멘틱을 유지하기 위해 부호 없는 정수들을 부호가 있는 것으로 대치하지 않습니다.
사용하지 않는 것이 좋은 케이스
부호 없는 정수가 0과 그 이상의 양수만 표현할 수 있기는 하지만, 음수이면 안되는 숫자가 필요하다고 해서 부호 없는 정수 타입을 사용하지는 않는 것이 좋습니다. 예를 들면, 컬렉션의 크기나 인덱스 등에서요.
아래의 몇몇가지 이유가 있습니다:
- 부호 있는 정수가 우발적인 오버플로우나 오류의 신호를 전달할 때 유용할 수 있습니다.
List.lastIndex
가 빈 리스트에 대해 -1 을 리턴하는 동작에서 볼 수 있듯이요. - 부호 없는 정수는 부호가 있는 그것의 범위를 제한한 것으로 간주될 수 없습니다. 그들의 표현 가능 범위는 부호가 있는 타입의 부분집합이 아니며, 각각이 서로와 어떠한 부분집합 관계도 갖지 않습니다.
이 페이지가 도움이 되셨다면, 원문 페이지에 방문해 엄지척을 해주세요!