프로그래밍 노트/Kotlin

스레드와 코루틴 스레드 Thread 클래스의 인스턴스는 프로그램이 실행될 때 운영체제의 네이티브 스레드를 나타낸다. 스레드(Thread)의 각 인스턴스는 해당 스택에 대한 메모리를 사용하고 초기화하기 위한 시간이 필요하다. 스레드의 컨텍스트 전환은 꽤 비싼 작업이기 때문에 별도의 스레드에서 짧은 작업을 호출하는 것은 좋은 결과를 가져오기 어렵다. 코루틴 (CoRoutine) 코루틴은 힙 메모리의 객체를 의미하며 코루틴 간의 전환은 운영체제 커널 작업이 아니다. 코루틴은 프로세스에 할당된 힙 메모리 영역을 공유해서 사용한다. 즉, 스레드에 비해 빠르고 적은 비용으로 생성할 수 있으며 자원도 적게 사용된다. 간단 사용법 코루틴은 CoroutineContext 인터페이스로 표시되는 컨텍스트에서 실행된다. El..
고차함수? 다른 함수를 인자로 받거나 함수를 반환하는 함수(파라미터 혹은 반환 값으로 람다 사용) 함수 타입이란? 함수 타입은 아래와 같이 선언 // 타입 추론 val sum = { x: Int, y: Int -> x + y } // 구체적인 타입 선언 val sum: (Int, Int) -> Int = { x, y -> x + y } 인자로 받은 함수 호출 간단한 고차 함수 정의 fun twoAndThree(operation: (Int, Int) -> Int) { val result operation(2, 3) println("The result is $result") } 함수 타입 파라미터에 디폴트 값 지정 fun Collection.joinString( separator: String = ", ",..
kotlin 데이터 클래스는 구조 분해 선언(Destructuring Declaration)이라는 특성을 갖고 있다. 구조 분해를 사용하면 복합적인 값을 분해해서 여러 다른 변수를 한꺼번에 초기화할 수 있다. val p = Point(10, 20) val (x, y) = p // x => 10 // y => 20 구조 분해 선언의 각 변수를 초기화하기 위해 componentN이라는 함수를 호출한다. data 클래스의 주 생성자에 들어있는 프로퍼티에 대해서는 컴파일러가 자동으로 componentN함수를 만들어준다. val (x, y) = p // 위 코드 컴파일 후 val x = p.component1() val y = p.component2() // data 타입이 아닌 클래스에서 구현하는 방법 clas..
인덱스로 원소에 접근 - Map 원소 접근시 괄호([]) 사용 코틀린에서는 맵의 원소에 접근할 때 자바에서 배열 원소에 접근하는 각 괄호([])를 사용할 수 있다. 인덱스 연산자는 get/set 관례를 따르며, Map과 MutableMap 인터페이스에는 이미 두 메서드가 들어가 있다. val value = map[key] mutableMap[key] = newValue 구현 예시 operator fun Point.get(index: Int): Int { return when(index) { 0 -> x 1 -> y else -> throw IndexOutOfBoundsException("Invalid coordinate $index") } } val p = Point(10, 20) println(p[1]..
산술 연산자 오버로딩 이항 산술 연산 오버로딩 (+, -, *, /) 함수 앞에 operator 키워드를 붙이면 연산자 오버로딩이 가능하다. data class Point(val x: Int, val y: Int) { operator fun plus(other: Point): Point) { // plus 이름의 연산자 함수를 정의 return Point(x + other.x, y + other.y) } } val p1 = Point(10, 20) val p2 = Point(30, 40) println(p1 + p2) >> Point(x = 40, y = 60) >> p1 + p2 는 p1.plus(p2)로 컴파일 된다. 미리 정해둔 연산자만 오버로딩 가능 식 함수 a * b times a / b div..
코틀린은 원시 타입/래퍼 타입을 구분하지 않는다. Int, Boolean 등등 코틀린은 자바와 달리 원시타입과 래퍼타입이 따로 존재하지 않는다. var list: List = listOf(1, 2, 3) 코틀린에서 모든 타입이 참조 타입으로 표현되는 것이 아니라, 실행 시점에 가능한 가장 효율적인 방식으로 타입이 표현된다. 대부분의 경우 코틀린의 Int타입은 자바 int 타입으로 컴파일 된다. 컴파일이 불가능한 경우(제네릭 클래스)만 래퍼 타입(Integer)로 컴파일되게 된다. Int를 컬렉션의 타입 파라미터로 넘길 때, Integer객체가 들어가게 된다. 널이 될 수 있는 타입 Int?, Boolean? 코틀린에서 널이 될 수 있는 원시 타입을 사용하면, 자바의 래퍼 타입으로 컴파일 된다. 자바의 래..
엘비스 연산자(?:) 코틀린은 엘비스 연산자(?:)를 사용하여 디폴트 값을 편하게 지정할 수 있다. fun foo(s: String?) = s ?: "" fun strLenSafe(s: String?): Int = s?.length ?: 0 return이나 throw등의 연산도 식이니, 엘비스 연산자의 우항에 넣을 수도 있다. fun printlnShippingLabel(person: Person){ val address = person.company?.address ?: throw IllegalArgumentException("No address") with(address){ println(streetAddress) println("$zipCode $city, $country") } } 안전한 캐스트:..
널 가능성 코틀린을 비롯한 최신 언어에서 null에 대한 접근 방법은 가능한 한 이 문제를 실행 시점에서 컴파일 시점으로 옮기는 것이다. 널이 될 수 있는지 여부를 타입 시스템에 추가함으로써 컴파일러가 여러 가지 오류를 커파일 시 미리 감지해서 실행 시점에 발생할 수 있는 예외의 가능성을 줄인다. 널이 될 수 있는 타입 코틀린과 자바의 차이점 중 하나는 코틀린 타입 시스템이 널이 될 수 있는 타입을 명시적으로 지원한다는 점이다. 코틀린은 null이 될 수 있는 변수를 메소드 파라미터로 받을 수 있으면 호출을 금지함으로써 많은 오류를 방지한다. int strLen(String s){ return s.length; } 이 함수의 파라미터로 null이 들어오면 NullPointerException이 발생한다...
코틀린 람다의 독특한 기능은 바로 수신 객체를 명시하지 않고 람다의 본문 안에서 다른 객체의 메소드를 호출할 수 있게 하는 것이다. 그런 람다를 수신 객체 지정 람다(lamda with receiver) 라고 부른다. with 함수 어떤 객체의 이름을 반복하지 않고도 그 객체에 대해 다양한 연산을 수행할 수 있을 때 사용한다. fun alphabet(): String{ val result = StringBuilder() for(letter in 'A'..'Z'){ result.append(letter) } result.append("\nNow I know the alphabet!") return result.toString() } 이 예제에서 result에 대해 다른 여러 메..
컬렉션 연산시 지연(lazy), 즉시(eagerly) 계산의 차이는 무엇인가? 즉시(eagerly)연산은 커렉션함수를 연쇄할 때마다 계산 중간 결과를 새로운 컬렉션에 임시로 담는다. 시퀀스(sequence)를 사용하면 중간 임시 컬렉션을 사용하지 않고 컬렉션 연산을 연쇄한다. people .filter { it.lastName != null } .filter { it. age!= null } .find { it.age == 31 } people.asSequence() // 컬렉션을 시퀀스로 변환 .filter { it.lastName != null } // Intermediate operation .filter { it. age!= null } // Intermediate operation .find {..
깡냉쓰
'프로그래밍 노트/Kotlin' 카테고리의 글 목록