Kotlin Advanced

mohadang·2023년 9월 18일
0

Kotlin

목록 보기
3/3
post-thumbnail

고차 함수

함수를 마치 클래스에서 만든 인스턴스처럼 취급하는 방법.

  • 함수를 파라미터로 넘겨줄 수 있음.
  • 함수를 결과 값으로 반환 받을 수 있음.

코틀린에서는 모든 함수를 고차 함수로 사용 가능

함수형 타입 선언 방식

'Unit' : 반환이 없다.
'::a' : 고차함수 넘길려면 앞에 :: 붙여야함.

람다 함수

일반 함수와 달리 그 자체가 고차 함수이다.

(String) : 파라미터 자료형.
str : 받아올 인자. 파라미터에서 자료형을 결정 하였기에 뒤에 String은 생략 가능.

반환

No Parameter

only 1 parameter

스코프 함수

인스턴스의 속성, 함수를 사용하기 쉽게 보조하는 함수.

이 보조 함수들은 임시적인 스코프를 생성하여 인스턴스를 사용하기 쉽게 보조한다.

apply

  • 인스턴스의 변수와 함수 조작 가능.
  • apply는 인스턴스 자신을 반환.

run

with

  • 파라미터로 넘겨 받는 차이가 있을 뿐 그 이외 차이가 없다.

also/let

  • also : apply와 같은 기능 가지고 있음. 대신 it을 통해 파라미터로 전달 받아 사용 가능. 처리가 끝나면 인스턴스를 반환.
  • let : run과 같은 기능 가지고 있음. 대신 it을 통해 파라미터로 전달 받아 사용 가능. 처리가 끝나면 최종값을 반환.
  • it을 사용하는 이유는 같은 이름의 외부 변수와 혼란을 막기 위해.
  • also/let만 써도 될 것 같음.

오브젝트(Singleton)

코틀린은 언어차원에서 싱글턴을 지원한다.

오브젝트는 그 자체로 인스턴스이다. 따라서 별도의 인스턴스를 생성하지 않으며 생성자도 없다.

오브젝트는

Companion Object(Static Member)

옵저버 패턴(이벤트 리스너, 콜백, ...)

fun main() {
    EventPrinter().start()// 인스턴스를 변수에 할당하지 않음
}

interface EventListener {
    fun onEvent(count: Int)
}

class Counter(var listener: EventListener) {
    fun count() {
        for (i in 1..100) {
            if (i % 5 == 0) listener.onEvent(i);
        }
    }
}

class EventPrinter : EventListener {
    override fun onEvent(count: Int) {
        println("Count: $count")
    }
    fun start() {
        val counter = Counter(this)
        counter.count()
    }
}

익명 객체

fun start() {
    // object 키워드 사용하여 클래스 정의와 인스턴스 생성을 동시에 처리
    val counter = Counter(object : EventListener { // EventListener 상속
        override fun onEvent(count: Int) { // EventListener onEvent 구현
            println("Count: $count")
        }
    })
    counter.count()
}

is, as

as : 캐스팅에 사용된 변수 b 자체도 다운 캐스팅 된다.

is, as 는 캐스팅을 한다. 캐스팅을 하고싶지 않다면 generic 사용.

generic

클래스

open class Base {
    open fun shout() {
        println("Base")
    }
}

class A : Base() {
    override fun shout() {
        println("A")
    }
}

class B : Base() {
    override fun shout() {
        println("B")
    }
}

class UsingGeneric<T: Base> (val t: T) {
    fun doShouting() {
        t.shout()
    }
}

함수

List

2가지 유형의 List

String

공백(' ', '\t', '\r', '\n')만 있는 문자열도 true 반환

null check

null safe

elvis

non-null assertion

  • null일 경우 런타임 에러(null pointer exception)

Ex)

tip) if 문 대신 사용하기 좋다

동일성


내용의 동일성

  • ex) 문자열 내용이 같은가 ?

객체의 동일성

  • ex) 같은 객체를 참조 하는가 ?

내용의 동일성이 사용될때 모든 클래스가 상속 받는 Any 클래스(최상위)의 equals() 호출한다.

경우에 따라 사용자 정의 함수에서 equals()를 재정의 해야 한다.

overloading

코틀린도 다른 일반 언어처럼 함수 시그니처 타입 구성이 같다면 오버로딩 불가

arguments

코틀린도 기본 파라미터와 named 파라미터 지원 한다.

vararg(variable number of arguments)

다른 파라미터와 사용할 경우 맨 마지막에 위치해야 한다.

infix

looks like C# extension method...

  • Int가 사용할 multiply 함수 정의.
  • 인자는 x:Int, 반환값도 Int.
  • this는 연산자 함수 호출시 왼쪽항, x 인자는 우측항이 대입된다.
  • 클래스 내부에서 사용할시 this는 클래스 자기 자신.

중첩 클래스, 내부 클래스

중첩 클래스 : 하나의 클래스가 다른 클래스의 기능과 강하게 연관되어 있다는 의미를 전달하기 위해 사용.

내부 클래스 : 혼자서 객체 생성 불가하고 외부 클래스 객체가 있어야만 생성/사용 가능.

Ex)

Nested Class
Inner Class
Outer Class
CHanged Outer Class

Data Class

데이터를 다루는데 최적화된 클래스로 5가지 기능을 자동으로 생성.

copy()의 경우 파라미터를 주면 일부 속성을 변경 가능.

componentX()을 사용하여 송성에 접근 가능.

  • 사실 이 함수는 사용자가 직접 호출하기 위해서 구현된것이 아닌 배열에서 값을 꺼낼때 사용하기 위해 구현 되었다.

Ex)

내부적으로 component 사용하여 출력

Enum Class

생성자로 값 설정 가능

함수도 추가 가능, 단 마지막에 정의 해야함.

Ex)

Set, Map

Set

Map

Collection 1

컬렉션 함수 : List, Set, Map과 같은 컬렉션, 배열에 일반 함수, 또는 람다 함수 형태로 사용하여 아이템을 열거(for, iter, ...)를 하거나 조건을 걸고, 구조의 변경까지 가능한 여러가지 함수를 지칭함.

first, last, count 함수도 있으며 다음과 같은 조건 함수도 있다.

Collection 2

이름을 키, 객체를 value로 하는 Map 반환.

속성 기준 배열을 사용한 그룹핑 Map 반환.

조건 기준으로 2 그룹으로 나누는 Pair 반환(first, second로 참조).

collection에 [2, 3] 들어있는 상태에서 flatMap을 시전하면 [6,5,9,6] 반환.

collection에 인덱스 8이 있을 경우 값을 가져오가 없으면 50을 가져옴.

Zip

  • 결과의 갯수는 아이템의 갯수가 적은 컬렉션을 따라감.

Ex)

변수 사용시 주의

val(var와 달리 다른값 대입 X)는 할당된 객체를 바꿀 수 없을 뿐이지 객체 내부 속성을 바꾸지 못하는 것은 아니다.(const 변수)

const는 string 포함 기본 자료형만 가능하며 객체같이 런타임에 변경 가능한 자료형은 변경 사용 불가.

const는 클래스 멤버 변수, 함수 지역 변수로 사용 불가하며 반드시 companion object 안에서만 사용 가능.

  • 객체의 생성과 관계 없이 사용하기 위해

lateinit(늦은 초기화)

코틀린에서 변수를 초기화 하지 않을 경우 컴파일 에러가 발생 하는데 이를 우회하는 방법이 lateinit이다.

제한 사항

  • 초기값 할당 전까지 변수를 사용할 수 없음(에러)
  • 기본 자료형에는 사용할 수 없음(String 사용 가능)

lateinit 변수 초기화 하였는지 확인.

Ex)

lazy

lateinit과 비슷. 하지만 나중에 초기화를 하지 않더라도 변수를 사용하게 되면 알아서 lazy에서 정의한 값으로 초기화 하고 사용.

람다이므로 다음과 같이 사용 가능

Ex)

bit 연산

코루틴(비동기처리)

메인 루틴 이외에 별도로 실행되는 루틴의 단위.

Scope : 코루틴은 제어범위 및 실행범위 지정 가능.

  • GlobalScope : 프로그램 어디서나 제어, 동작이 가능한 코루틴 범위.
  • CoroutineScope : 특정한 목적의 Dispatcher를 지정하여 제어 및 동작이 가능한 새로운 코룬틴 범위 생성.

코루틴의 dispatcher.

  • CoroutineScopef를 만들 때 적용 가능한 Dispatcher.

!!! Dispatcher 들은 모든 플랫폼에서 지원되지 않으니 지원 되는 플랫폼에서 사용 !!!

코루틴은 launch, async 키워드를 사용하여 생성 가능.

launch : 반반환값이 없는 Job 객체.
async : 반환값이 있는 Deffered 객체.

!!! 안드로이드에서 runBlocking을 걸어준 후 일정 이상 응답이 없으면 ANR이 발생 하면서 앱이 자동 종료.

Ex) runBlocking 사용하여 코루틴 종료 될때까지 대기.

!!! delay, async, launch, await, join, ... 이런 키워드는 루틴의 대기 가능한 블록(runBlocking) 안에서만 동작이 가능.

cancel

코루틴에 cancel 사용시 발생할 수 있는 2가지 경우

Ex)

숫자가 끊김. for 안의 delay에서 취소됨.

withTimeoutOrNull

이 함수도 join, await처럼 블록킹 함수이다.

Ex) 타임아웃 내에 실행할 수 없어 null 반환

profile
mohadang

0개의 댓글