프로그래밍백엔드 개발자

코틀린에서 숫자 범위 메커니즘을 설명하세요: Range와 Progression이 어떻게 작동하는지, 사용자 정의 범위를 생성하는 방법 및 어떤 시나리오에서 유용하게 사용할 수 있는지.

Hintsage AI 어시스턴트로 면접 통과

답변

질문의 역사

코틀린에서는 처음부터 범위(Range)를 도입하여 연속적인 값 집합에 대한 작업을 간소화했습니다. 이는 숫자 처리에 있어 간결한 구문을 제공하는 언어(예: 파이썬)에서 상속된 것입니다. 또한, Range 메커니즘은 Progression으로 확장되어 반복 단계와 여러 숫자 및 문자 타입을 지원합니다.

문제

정수, 문자, 시간 지점 등을 반복하는 것은 종종 특정 구문과 표준 라이브러리의 신뢰성을 요구합니다. 그렇지 않으면 코드가 복잡해지고 읽기 어려우며 경계 오류에 취약해집니다.

해결책

코틀린에는 IntRange, CharRange, LongRange와 단계별 반복을 위한 Progression이 있습니다. 또한 어떤 비교 가능한 타입에 대해서도 범위를 정의할 수 있습니다.

// 간단한 범위 for (i in 1..5) print(i) // 12345 // 단계가 있는 범위 for (i in 1..10 step 2) print(i) // 13579 // 역범위 for (i in 5 downTo 1) print(i) // 54321 // 사용자 정의 범위(예: Version) data class Version(val major: Int, val minor: Int): Comparable<Version> { override fun compareTo(other: Version): Int = compareValuesBy(this, other, Version::major, Version::minor) } operator fun ClosedRange<Version>.iterator(): Iterator<Version> = object : Iterator<Version> { var current = start override fun hasNext() = current <= endInclusive override fun next() = current.also { current = Version(current.major, current.minor + 1) } } val v1 = Version(1, 0) val v2 = Version(1, 3) for (v in v1..v2) println(v)

주요 특징:

  • 표준 범위 구문: .., downTo, until, step
  • 숫자, 문자, 사용자 정의 타입과의 작업
  • 루프, 포함 여부 검사, 분할, 유효성 검사에 적용

트릭 질문.

1..51 until 5의 차이점은 무엇인가요?

1..5는 범위의 양 끝을 포함합니다: 1,2,3,4,5. 1 until 5는 마지막 요소를 포함하지 않습니다: 1,2,3,4.

step을 사용하여 0보다 작은 단계의 범위를 지정할 수 있나요?

아니요. 감소하는 범위의 경우 downTo 구문을 사용하고 그 다음에 step을 사용하세요: 5 downTo 1 step 2 (5, 3, 1이 나옵니다).

Comparable을 구현하지 않는 타입으로 범위를 사용할 수 있나요?

아니요. 범위를 만들려면 타입이 비교를 지원해야 합니다. 그렇지 않으면 컴파일러가 정의를 허용하지 않습니다.

일반적인 오류 및 안티 패턴

  • .. 대신 until을 사용하거나 그 반대로 경계 포함에 대한 혼동
  • 증가하는 범위에 대해 음수 단계를 지정 (step이 범위를 역전시키지 않음)
  • 사용자 정의 타입의 범위에서 Comparable 요구사항을 준수하지 않음

실제 사례

부정적인 케이스

코드에서 1 until n+1 대신 1..n을 사용했습니다. 우리는 추가 요소를 얻고, 루프가 허용된 범위를 초과합니다.

장점:

  • 의도치 않게 가장자리를 포함하게 됨.

단점:

  • 분할 시 오류, 경계에서 잘못된 합계 계산.

긍정적인 케이스

배열 길이가 n인 경우 인덱싱을 위해 for (i in 0 until n)을 사용합니다. 범위는 인덱스의 허용 값과 정확히 일치합니다.

장점:

  • 배열 경계 초과 오류를 방지.
  • 가독성 향상.

단점:

  • 언어 간 전환 시 ..until의 차이를 기억해야 함.