표준 함수와 파일 입출력 (1/2)

장똑대·2022년 4월 27일
0

Do it! 코틀린 프로그래밍 [셋째마당, 코틀린 표준 라이브러리의 활용] 학습

✏️1. 코틀린 표준 함수✏️

표준함수는 람다식과 고차함수를 이용해 선언되어 있음
표준함수를 이용하면 코드를 더 단순화하고 읽기좋게 만들 수 있음


1-1. 클로저 (Closure)

  • 람다식으로 표현된 내부 함수에서 외부 범위에 선언된 범수에 접근할 수 있는 개념
  • 람다식 안에 있는 외부 변수는 값을 유지하기 위해 람다식이 포획(Capture)한 변수라고 부름
  • 포획한 변수는 참조가 유지되어 함수가 종료되어도 사라지지ㅇ 않고 함수의 변수에 접근하거나 수정할 수 있게 해줌

📌 클로저의 조건

  • final 변수를 포획한 경우 변수 값을 람다식과 함께 저장
  • final이 아닌 변수를 포획한 경우 변수를 특정 래퍼(Wrapper)로 감싸서 나중에 변경하거나 읽을 수 있게 한다. 이떄 리퍼에 대한 참조를 람다식과 함께 저장한다
fun main() {
    val calc = Calc()
    var result = 0 // 외부의 변수
    calc.addNum(2, 3) { x, y -> result = x + y } // 클로저
    println(result) // 값을 유지하여 5 출력
}

class Calc {
    fun addNum(a: Int, b: Int, add: (Int, Int) -> Unit) {
        add(a, b)
    }
}

-> Calc클래스의 메서드인 addNum()이 호출되면 result는 자신의 유효범위를 벗어나 삭제되어야하지만 클로저의 개념에 의해 독립된 복사본을 가짐


1-2. 코틀린의 표준 라이브러리

📌 확장 함수의 람다식 접근 방법

함수 이름람다식의 접근 방법반환 방법
T.letitblock 결과
T.alsoitT caller (it)
T.applythisT caller(this)
T.run / runthisblock 결과
withthisUnit

📌 let() 함수

  • public inline fun <T, R> T.let(block: (T) -> R): R { ... return block (this)}
  • 제네릭의 확장 함수 형태이므로 어디든 적용할 수 있음
  • 이 함수를 호출한 객체를 인자로 받으므로 이를 사용하여 다른 메서드를 실행하거나 연산을 수행해야하는 경우 사용
// (1)
val padding = TypedValue.applyDimension(
	TypeValue.COMPLEX_UNIT_DIP, 16f, resources.displayMetrics).toInt()

setPadding(padding, 0, padding, 0)

// (2) let() 함수 사용 (변수 X)
val padding = TypedValue.applyDimension(
	TypeValue.COMPLEX_UNIT_DIP, 16f, resources.displayMetrics).toInt().let { 
    setPadding(it, 0, it, 0)
}

-> (1)에서는 padding이 한번만 사용되면 변수 할당을 하느라 자원 낭비가 있을 수 있음
-> 이때 (2)와 같이 let()을 통해 변수를 따로 할당하지 않는 방법을 사용할 수 있음

  • 앨비스 연산자(?:)를 사용해 if-else문을 한줄로 단순화 할 수 있음
firstName?.let { print("$it $lastName") } ?: print("$lastName")

📌 also() 함수

  • public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
  • 블록 안의 코드 수행 결과와 상관없이 T인 객체 this를 반환
var m = 1
m = m.also { it + 3 }
println(m) // 원본값 1

-> 연산 결과인 4가 할당되는 것이 아니라 it의 원래 값 1이 다시 m에 할당

  • let() 함수와 비교
fun main() {
    data class Person(var name: String, var skills: String)
    
    var person = Person("Kildong", "Kotlin")
    val a = person.let { 
        it.skills = "Android"
        "success"
    }
    println(a) // success
    
    val b = person.also { 
        it.skills = "Java"
        "success"
    }
    println(b) // Person("Kildong", "Java"
}

-> let() 함수는 마지막 표현식인 "success"를 a에 할당
-> also()는 마지막 표현식 "success"을 b가 아닌 person객체 자신에 할당
-> b는 Person의 객체 person을 반환하고 새로운 객체 b가 할당되어 만들어짐

profile
장똑대와 안드로이드

0개의 댓글

관련 채용 정보