Programming/Kotlin26 코틀린(kotlin) - 우선순위큐(PriorityQueue) 정렬 기준 백준 또는 CodeForce 등을 풀다보면 우선순위 큐를 사용할 일이 많다. 이 때 우선 순위 큐에 들어가는 자료형이 Int, Double, String 등 한개로만 이루어져 있다면, 아무 조건없이 넣었을 때 오름차순으로 정렬될테고, reverseOrder() 명령어를 통해 역순으로 정렬할 수도 있다. val pq = PriorityQueue() pq.add(1) pq.add(2) pq.add(3) val rpq = PriorityQueue(reverseOrder()) rpq.add(1) rpq.add(2) rpq.add(3) /* pq -> 1, 2, 3 rpq -> 3, 2, 1 */ 하지만 자료형이 하나가 아닌, Pair 또는 Triple 혹은 데이터 클래스와 같은 것을 PriorityQueue의 .. Programming/Kotlin 2022. 8. 7. 코틀린(kotlin) - 리플렉션: 실행 시점에 코틀린 객체 내부 관찰 리플렉션을 간단하게 말하면 실행 시점에 동적으로 객체의 프로퍼티와 메소드에 접근할 수 있게 해주는 방법이다. 보통 객체의 메소드나 프로퍼티에 접근할 때, 컴파일러는 메소드나 프로퍼티의 이름이 실제로 가리키는 선언을 컴파일 시점에 찾아내 해당하는 선언이 실제 존재함을 보장한다. 하지만 타입과 관계없이 객체를 다뤄야 하거나 객체가 제공하는 메소드나 프로퍼티 이름을 오직 실행 시점에만 알 수 있는 경우라면 리플렉션을 사용해야 한다. 코틀린에서 리플렉션을 사용하기 위해선 두 가지의 다른 리플렉션 API를 다뤄야 한다. 첫 번째는 자바가 java.lang.reflect 패키지를 통해 제공하는 표준 리플렉션이다. 코틀린 클래스는 일반 자바 바이트코드로 컴파일되므로 자바 리플렉션 API도 코틀린 클래스를 컴파일한 바.. Programming/Kotlin 2021. 12. 26. 코틀린(kotlin) - 애노테이션 선언과 적용 애노테이션 적용 코틀린에선 자바와 같은 방법으로 애노테이션을 사용할 수 있다. 적용하려는 대상 앞에 애노테이션을 붙이는 것이다. 애노테이션은 @와 애노테이션 이름으로 이뤄지며 함수나 클래스 등 여러 다른 코드 구성 요소에 붙일 수 있다. import org.junit.* class MyTest { @Test fun testTrue() { Assert.assertTrue(true) } } 애노테이션에 인자를 넘길 때는 일반 함수와 마찬가지로 괄호 안에 인자를 넣는다. @Deprecated("Use removeAt(index) instead.", ReplaceWith("removeAt(index)")) fun remove(index: Int) { ... } 이런 remove 함수 선언이 있다면 remove를.. Programming/Kotlin 2021. 12. 19. 코틀린(kotlin) - 애노테이션 선언과 적용 에노테이션 적용 코틀린에선 자바와 같은 방법으로 애노테이션을 사용할 수 있다. 적용하려는 대상 앞에 애노테이션을 붙이는 것이다. 애노테이션은 @와 애노테이션 이름으로 이뤄지며 함수나 클래스 등 여러 다른 코드 구성 요소에 붙일 수 있다. import org.junit.* class MyTest { @Test fun testTrue() { Assert.assertTrue(true) } } 애노테이션에 인자를 넘길 때는 일반 함수와 마찬가지로 괄호 안에 인자를 넣는다. @Deprecated("Use removeAt(index) instead.", ReplaceWith("removeAt(index)")) fun remove(index: Int) { ... } 이런 remove 함수 선언이 있다면 remove를.. Programming/Kotlin 2021. 12. 19. 코틀린(kotlin) - 변성: 제네릭과 하위 타입 변성(variance)은 List와 List )와 같이 기저 타입이 같고 타입 인자가 다른 여러 타입이 서로 어떤 관계가 있는지 설명하는 개념이다. 변성이 있는 이유: 인자를 함수에 넘기기 String 클래스는 Any를 확장하므로 Any 타입 값을 파라미터로 받는 함수에 String 값을 넘겨도 절대 안전하다. 하지만 Any와 String이 List 인터페이스의 타입 인자로 들어가는 경우에는 절대 안전하다고 말할 수 없다. 리스트의 내용을 출력하는 함수를 보자. fun printContents(list: List) { println(list.joinToString()) } >>> printContents(listOf("abc", "bac")) abc, bac 이 경우에는 각 원소를 Any로 취급하며 모든.. Programming/Kotlin 2021. 12. 12. 코틀린(kotlin) - 실행 시 제네릭스의 동작 소거된 타입 파라미터와 실체화된 타입 파라미터 JVM의 제네릭스는 보통 타입 소거(type erasure)를 사용해 구현된다. 이는 실행 시점에 제네릭 클래스의 인스턴스에 타입 인자 정보가 들어있지 않다는 뜻이다. 함수를 inline으로 만들면 타입 인자가 지워지지 않게 할 수 있다. 이를 코틀린에선 "실체화"라고 한다. 실행 시점의 제네릭: 타입 검사와 캐스트 자바와 마찬가지로 코틀린 제네릭 타입 인자 정보는 런타임에 지워진다. -> 제네릭 클래스 인스턴스가 그 인스턴스를 생성할 때 쓰인 타입 인자에 대한 정보를 유지하지 않는다. 예를 들어 List 객체를 만들고 그 안에 문자열을 여럿 넣더라도 실행 시점에는 그 객체를 오직 List로만 볼 수 있고, 어떤 타입의 원소를 저장하는지 알 수 없다.' va.. Programming/Kotlin 2021. 11. 27. 코틀린(Kotlin) - 제네릭 타입 파라미터 제네릭 타입 파라미터 제네릭스를 사용하면 타입 파라미터(type parameter)를 받는 타입을 정의할 수 있다. 제네릭 타입의 인스턴스를 만들려면 타입 파라미터를 구체적인 타입 인자(type argument)로 치환해야 한다. -> 만약 List 타입이 있을 때 그 안의 원소의 타입을 알 때, 타입 파라미터를 사용하면 "이 변수는 리스트이다." 가 아닌 "이 변수는 문자열을 담는 리스트이다."라고 할 수 있다. 코틀린 컴파일러는 보통 타입과 마찬가지로 타입 인자도 추론 가능하다. val authors = listOf("Dmitry", "Svetlana") listOf에 전달된 두 값이 문자열이기 때문에 컴파일러는 이 리스트가 List이라 추론한다. 빈 리스트를 만들 때는 타입 인자를 추론할 근거가 없.. Programming/Kotlin 2021. 11. 21. 코틀린(Kotlin) - 고차 함수 안에서 흐름 제어 람다 안의 return문: 람다를 둘러싼 함수로부터 반환 data class Person(val name: String, val age: Int) val people = listOf(Person("Alice", 29), Person("Bob", 31)) fun lookForAlice(people: List) { for(person in people) if(person.name = "Alice") { println("Found!") return } } println("Alice is not found") } >>> lookForAlie(people) Found! for문을 forEach 함수로 바꾸어도 루프의 기능은 동일하다. forEach에 넘긴 람다 안에 있는 return도 같은 의미이기 때문이다. f.. Programming/Kotlin 2021. 11. 14. 코틀린(Kotlin) - 인라인 함수 람다를 활용한 코드에선 무명 클래스 생성에 따른 부가 비용이 든다. 이 때문에 같은 작업을 수행하는 일반 함수를 사용한 구현보다 효율적이지 못하다. inline 변경자를 어떠한 함수에 붙이면 컴파일러는 그 함수를 호출하는 모든 문장을 함수 본문에 해당하는 바이트코드로 바꿔 일반 명령문과 같은 효율적인 코드를 생성하게 해 준다. 인라이닝이 작동하는 방식 위에서도 말했듯이 어떤 함수를 inline 선언하면 그 함수의 본문이 인라인 된다. 다른 말로 "함수를 호출하는 코드를 함수를 호출하는 바이트코드 대신 함수 본문을 번역한 바이트 코드로 컴파일하는 것이다." inline fun synchronized(lock: Lock, action: () -> T): T { lock.lock() try { return a.. Programming/Kotlin 2021. 11. 12. 코틀린(Kotlin) - 고차 함수 정의 고차 함수 정의 고차 함수는 다른 함수를 인자로 받거나 함수를 반환하는 함수이다. 코틀린은 람다나 함수 참조를 사용해 함수를 값으로 표현할 수 있으므로 고차 함수는 람다나 함수 참조를 인자로 넘길 수 있거나 함수 참조를 반환하는 함수인 것이다. ex) filter 함수는 술어 함수를 인자로 받으므로 고차 함수이다. list.filter(x > 0) 함수 타입 // 타입 추론 val sum = {x: Int, y: Int -> x + y} val action = { println(42) } // 함수 타입 선언 val sum: (Int, Int) -> Int = {x, y -> x + y} val action: () -> Unit = { println(42) } 함수 타입을 선언할 때는 반환 타입을 반드시.. Programming/Kotlin 2021. 11. 6. 코틀린(Kotlin) - 연산자 오버로딩과 기타 관례 어떤 클래스 안에 plus라는 이름의 특별한 메소드를 정의한다면 그 클래스의 인스턴스에 대해 + 연산자를 사용할 수 있다. 이런 식으로 어떤 언어 기능과 미리 정해진 이름의 함수를 연결해주는 기법을 코틀린에선 관례라고 한다. 코틀린에서는 언어 기능을 타입에 의존하는 자바와 달리 관례에 의존한다. 이는 기존 자바 클래스를 코틀린 언어에 적용하기 위해서이다. 기존 자바 클래스가 구현하는 인터페이스는 이미 고정돼 있고, 코틀린에서 자바 클래스가 새로운 인터페이스를 구현하게 만들 수 없다. 하지만 확장 함수를 사용하면 기존 클래스에 새로운 메소드를 추가할 수 있다. 따라서 기존 자바 코드를 바꾸지 않아도 새로운 기능을 쉽게 부여할 수 있게 된다. 산술 연산자 오버로딩 산술 연산자는 코틀린에서 관례를 사용하는 가.. Programming/Kotlin 2021. 10. 31. 코틀린(Kotlin) - 컬렉션과 배열 널 가능성과 컬렉션 컬렉션 안에 널 값을 넣을 수 있는지의 여부는 어떤 변수의 값이 널이 될 수 있는지 여부와 같이 중요하다. 컬렉션 타입 인자 뒤에 ?를 붙이면 널이 될 수 있는 값으로 이루어진 컬렉션을 만들 수 있다. fun readNumbers(reader: BufferedReader) : List { val result = ArrayList() for (line in reader.lineSequence()) { try { val number = line.toInt() result.add(number) } catch(e: NumberFormatException) { result.add(null) } } return result } 코드를 보면 2행에서 List를 볼 수 있다. List는 Int? 타.. Programming/Kotlin 2021. 10. 24. 이전 1 2 3 다음 728x90