프로그래밍미들 코틀린 개발자

코틀린에서 스코프 함수(let, also, run, apply, with)란 무엇인가요? 이러한 함수의 차이점은 무엇이며, 다양한 작업에 대해 선택하는 방법은 무엇인가요? 사용 시 발생할 수 있는 미세한 차이점이 있나요? 예시를 들어주세요.

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

답변.

코틀린의 스코프 함수(“범위 함수”)는 객체의 코드 블록 실행 맥락을 관리할 수 있도록 하는 표준 함수(let, also, run, apply, with)입니다. 이들은 다음과 같은 점에서 다릅니다:

  • 반환 값의 타입,
  • 블록 내에서 객체의 접근 방식: it 또는 this를 통해.

간단 비교:

함수this/it반환용도
letit결과체인 작업, nullable 작업, 매핑
alsoit객체부작용, 로깅, 디버그
runthis결과계산, 반환과 함께 초기화
applythis객체객체 구성, 빌더
withthis결과외부 API 작업, 외부 객체 사용

예시:

  • let: nullable 객체에 편리함:
val str: String? = "Text" str?.let { println(it.length) }
  • apply: 객체 설정:
val paint = Paint().apply { color = Color.RED strokeWidth = 2f }
  • run: 객체에서 실행하고 결과 반환:
val length = "abcde".run { length }
  • with: 외부 객체 작업:
val sb = StringBuilder() with(sb) { append("Hello, ") append("world!") toString() }
  • also: 부작용을 위한 것 (예: 로깅):
val list = mutableListOf(1, 2, 3) list.also { println("Before: $it") }.add(4)

주의할 점:

  • letit에서 객체의 복사본을 생성하므로, 객체 속성을 변경하기가 그리 편리하지 않습니다.
  • applyalso는 항상 동일한 객체(this / it)를 반환하므로, 빌더에 유용합니다.
  • run/with는 자주 혼동됩니다: with는 일반 함수이며, 확장 함수가 아닙니다.

함정 질문.

let과 also의 차이점은 무엇인가요?

답변:

  • 두 함수 모두 블록 내에서 it를 사용합니다,
  • let은 람다의 결과를 반환하며, 종종 변환 체인에 사용됩니다,
  • also는 원래 객체를 반환하며, 부작용(로깅, 디버그 등)을 위해 사용되어 변환 체인에 영향을 미치지 않습니다.

예시:

val result = listOf(1).also { println(it) }.map { it * 2 } // 결과 — List<Int>

주의하지 않아 발생한 실제 오류 사례:


이야기

초심자는 객체를 "체인"에서 설정하기 위해 let을 사용하여, 설정 블록 종료 후 결과로 람다를 받아 객체가 아닌 결과값을 받았습니다(예: 아무것도 아님) 때문에 DSL 구축 과정이 깨졌습니다.


이야기

nullable 객체를 다루는 코드 작성을 할 때, let 대신 run을 사용하여 반환 값의 차이를 인식하지 못했습니다. 결국 표현식의 결과가 예상과 달라지고, null이 나타나는 등 애플리케이션의 논리가 깨졌습니다.


이야기

큰 빌더에서 우연히 내부 객체에 대해 with를 사용하여 확장 패턴에 기대했습니다. with는 확장 함수가 아니기 때문에 여러 with 블록 체인이 올바르게 작동하지 않았고, 내부 호출이 혼동되어 현 객체의 경계를 넘어갔습니다. 객체 생성 계층을 완전히 다시 작성해야 했습니다.