해당 글은
Kotlin in Action
도서를 읽으며 정리한 내용입니다
- 코틀린은 자체적으로 컬렉션 기능을 제공하지 않는다
- 표준 Java 컬렉션을 기반으로 더 많은 기능이 추가된 형태로 사용할 수 있다
(뒤에 나올확장 함수
덕분에 이것이 가능)
- 코틀린으로 작성한 함수를 호출할 때, 파라미터 이름을 명시할 수 있다
- 하나라도 파라미터 이름을 명시하려면, 혼동을 막기 위해 모두 명시 해야 함
- 디폴트 파라미터(default parameter)와 함께 유용하게 사용 가능
- 디폴트 파라미터로 인해 많은 오버로드(함수 중복 선언)을 막을 수 있음
/* 함수 호출시, 이름 명시 */ joinToString(collection, separator = "", prefix = "", postfix = "") /* 함수 정의시, 이름 명시 + 디폴트 값 지정 */ fun <T> joinToString( collection: Collection<T>, separator: String = "", prefix: String = "", postfix: String = "" )
- 최상위 함수
- class 밖인, 최상위에 위치되어 사용되는 함수
- Java에서는 클래스 밖에 위치할 수 없었지만, Kotlin에서는 가능
- 내부적으로 컴파일할 때 새로운 클래스를 정의해 주어서, JVM에 의해 실행될 수 있다
- Kotlin 컴파일러에 의해 결국 정적(static) 함수로 변환 된다
/* Kotlin */ fun joinToString(...): String { ... } /* Kotlin 컴파일러에 의해 변환된 결과 => 정적 함수 */ public static String joinToString(...) { ... }
- 최상위 프로퍼티
- 파일의 최상위 수준에 위치되어 사용되는 프로퍼티
- Kotlin 컴파일러에 의해 결국 정적(static) 코드로 변환이 된다
(정적 필드에 저장)/* Kotlin */ const val STR = "Kotlin"; /* Kotlin 컴파일러에 의해 변환된 결과 => 정적 변수 */ public static final String STR;
- 확장 함수
- 정의
- 최상위 함수 처럼 클래스 밖에 선언된 함수
- 클래스에 특정 함수를 확장하기 위한 목적
- 사용
{확장할 클래스의 이름}.{추가하는 함수 이름}
형식으로 함수 선언확장할 클래스 이름
을수신 객체 타입
이라고 부름- 확장 함수를 호출하기 위해서는 반드시 import를 해줘야 한다
- 특징
- 어떤 클래스의 멤버 메소드인 것 처럼 호출 가능
- 결과적으로, 확장함수는 정적 메소드 호출에 대한 문법적인 편의(
syntatic sugar
)일 뿐이다- 확장 함수를 통해 class를 간결하게 유지할 수 있다
(class 외부에 위치시킬 수 있기 때문)- 확장 함수는 오버라이드(override) 할 수 없다
- 정적 메소드와 같은 특징을 가진다
- 클래스의 일부가 아니기 때문에 상속이 안되고, 오버라이드 될 수 없다
/* String클래스에 마지막 문자를 돌려주는 함수를 추가 */ package.strings fun String.lastChar() : Char = get(length - 1) // 함수를 호출하는 쪽에서 확장 함수인지, 멤버 함수인지 구분할 수는 없다 // 그리고, 그 여부가 중요한 경우도 거의 없다 import strings.lastChar val c = "Kotlin".lastChar()
- 확장 프로퍼티
- 정의
- 최상위 프로퍼티 처럼 클래스 밖에 선언된 프로퍼티
- 클래스에 특정 프로퍼티를 확장하기 위한 목적
- 사용
{확장할 클래스의 이름}.{추가하는 프로퍼티 이름}
형식으로 프로퍼티 선언- 특징
- 기존 클래스의 인스턴스 객체에 필드를 추가할 방법이 X
-> 상태를 저장하지는 않기 때문
-> 즉, 그때 그때 evalution뒷받침하는 필드
(프로퍼티의 값을 저장하기 위한 필드
)가 없어서 최소한getter
는 정의 해주어야 한다
-> setter를 작성해도 추가 저장소를 갖는 것은 아니다- getter / setter 사용시 수신객체를 받아 짧게 작성 가능
/* 확장 프로퍼티 선언 */ var StringBuilder.lastChar: Char get() = get(length - 1) // getter set(value: Char){ // setter this.setCharAt(length - 1, value) } /* 확장 프로퍼티 사용 */ val sb = StringBuilder("Kotlin?") sb.lastChar = "!" // 추가 저장소 X, 기존 저장소 데이터 변경 println(sb) // Kotlin!
- 가변 길이 인자
...
연산자를 통해서, Java에서 메소드를 호출할 때 월하는 개수 만큼 값을 인자로 넘기면, 자바 컴파일러가 값을 넣어주는 기능- Kotlin 에서는
vararg
변경자와*
(스프레드 연산자) 를 통해 해당 기능을 사용한다/* 함수의 정의 */ // vararg 변경자로 여러개의 값을 받을 수 있도록 구현되어 있다 fun listOf<T> (vararg values: T) : List<T> { ... } /* 사용 */ fun main(args: Array<String>) { val list = listOf("args: ", *args) // *는 여기서 스프레드 연산자 이다 println(list) }
- 중위 함수 호출
- 인자가 하나뿐인 일반 메소드나, 확장 함수를 간략하게 호출하는 기능
infix
변경자를 함수에 추가해서 구현할 수 있다- 함수의 정의를 간략하게 줄이는 목적을 가진다
/* to 메소드에 중위호출을 위한 infix Pair 인스턴스를 반환하며, 이것은 두 원소로 이루어진 순서쌍을 표현한다 Any는 Java의 Object와 같은 인터페이스 */ infix fun Any.to(other: Any) = Pair(this, other) /* mapOf()를 통해 map을 만드는 예시 to라는 일반 메서드를 중위 호출로 사용하는 것이다 */ val map = mapOf(1 to "one", 2 to "two", 3 to "three")
- 구조 분해 선언
- 객체가 가지고 있는 값에서 필요한 값들만 바로 추출하는 기능
- JS의 구조 분해 / 비구조화 할당과 유사
/* to의 반환값인 Pair에서 number, name이라는 필드를 바로 추출하는 것 */ val (number, name) = 1 to "one"
- Kotlin 문자열은 Java 문자열을 포함하며 추가 기능 제공
(확장 함수를 통해 기능이 추가되어 있다)- 문자열 나누기
- Java에서는 string.split() 의 실제 파라미터가 정규식(regex)
- Kotlin에서는 정규식(regex)과 일반 텍스트 모두 가능
/* .과 -로 split하는 정규식 */ println("12.345-6.A".split("\\.|-").toRegex()) /* 여러개의 구분 문자열을 받아서 문자열을 나눌 수 있다 => Java는 불가능 */ println("12.345-6.A".split(".","-').toRegex())
- 3중 따옴표 활용
- 문자열 이스케이프를 피하기 위해서 사용 가능
- 줄 바꿈을 표현할 때 그대로 표현 가능
- Kotlin에서는 정규식 없이도 문자열을 쉽게 파싱할 수 있다
val Str : String = "/Users/Desktop/hue.zip" fun ParsePath(path: String){ val directory = path.substringBeforeLast("/") // "/Users/Desktop" val fullName = path.substringAfterLast("/") // hue.zip val fileName = fullName.substringBeforeLast(".") // hue val extension = fullName.substringAfterLast(".") // zip }
- Kotlin은 자체 컬렉션 클래스를 정의하지 않고,
Java 클래스
를확장
해서 사용한다함수 파라미터
의디폴트 값
을 정의하면,오버로딩한 함수
를 정의할 필요성이 줄어든다이름 붙인 인자
를 사용하면, 함수 호출의가독성
을향상
시킬 수 있다- Kotlin 파일에서
클래스 밖
에최상위 함수
와최상위 프로퍼티
를 선언할 수 있다확장 함수
와확장 프로퍼티
를 사용하면,외부 라이브러리의 클래스
를포함
해서확장
할 수 있다중위 호출
을 통해서인자가 하나 밖에 없는 메소드
나확장 함수
를 깔끔하게 사용할 수 있다- Kotlin은
정규식
과일반 문자열
을 처리할 때 유용한다양한 문자열 처리 함수
를 제공한다Java 문자열
에선많은 이스케이프
가 필요할 때, Kotlin은3중 따옴표 문자열
로 간단하게 표현할 수 있다