1. 함수 파라미터에 Defualt 값을 정의하면, 다양한 생성자를 정의할 필요성이 줄어든다, 또한 이름붙인 파라미터를 사용하면 함수 호출의 가독성을 향상시킬 수 있다.
- 자바와는 다르게, 파라미터에 어떤 인자를 세팅할 것인지 명시할 수 있다.
- 명시되지 않은 값은 Default 값으로 초기화된다.
class Person (
val age: Int = 0,
val name: String = "홍길동"
) {
}
fun main() {
val person1 = Person()
assertEquals(0, person1.age)
assertEquals("홍길동", person1.name)
val person2 = Person(age = 10)
assertEquals(10, person2.age)
assertEquals("홍길동", person2.name)
val person3 = Person(age = 30, name = "둘리")
assertEquals(30, person3.age)
assertEquals("둘리", person3.name)
}
2. 최상위 함수를 직접 선언할 수 있다.
- 클래스 내에 함수를 선언하는 것이 아닌, 소스코드 내 최상위에 함수를 선언할 수 있다.
- 자바에서는, @NoArgsConstructor(access=AccessLevel.Private) 로 선언한 뒤, 공통함수를 선언하는 것을
- 코틀린에서는 최상위 함수로 해결한다.
// xxx.kt 클래스에 최상위로 함수를 선언할 수 있다.
// import 하여 사용하면 된다.
fun sum(a : Int, b: Int) : Int {
return a + b
}
fun sub(a : Int, b : Int) = a - b
3. 최상위 프로퍼티를 직접 선언할 수 있다.
- 최상위 함수와 마찬가지로 최상위 프로퍼티를 선언할 수 있다.
// xxx.kt 클래스에 최상위로 함수를 선언할 수 있다.
// import 하여 사용하면 된다.
const val constVal = 1
val valueTest = 2
var variableTest = 3
// 자바로 디컴파일한 결과
public final class HighestValueKt {
public static final int constVal = 1;
private static final int valueTest = 2;
private static int variableTest = 3;
public static final int getValueTest() {
return valueTest;
}
public static final int getVariableTest() {
return variableTest;
}
public static final void setVariableTest(int var0) {
variableTest = var0;
}
}
4. 확장함수를 사용하여 외부 라이브러리에 정의된 클래스를 소스코드 변경없이 확장할 수 있다.
- 이 확장은 런타임에 부가적인 비용이 들지 않는다.
// 자바의 Integer 클래스를 확장하여, 받은 숫자보다 큰지 확인하는 메소드를 만들었다.
fun String.longerThan(num: Int) = length > num
fun main() {
assertTrue("abcdefg".longerThan(5))
assertFalse("abcdefg".longerThan(10))
}
런타임에 부가적인 비용이 들지 않는 이유
- 자바에서는 위의 확장함수를 정적함수로 변환하며 (우리는 그저 정적함수를 한개 만든 것일 뿐이다!)
- 첫번째 파라미터로 수신 객체 타입(확장을 적용한 클래스) 을 준다.
- 두번째 이후 파라미터로, 확장함수의 파라미터를 준다.
public final class Chapter3Kt {
public static final boolean longerThan(@NotNull String $this$longerThan, int num) {
Intrinsics.checkNotNullParameter($this$longerThan, "<this>");
return $this$longerThan.length() > num;
}
}
5. 중위(infix) 호출을 통해 인자가 하나 밖에 없는 메소드를 깔끔한 구문으로 호출할 수 있다.
- map 에 값을 추가하는 과정에서 아래와 같은 코드를 볼 수 있다.
fun main() {
val map = mapOf<Int, String>(1 to "one", 2 to "two", 3 to "three")
}
- [to] 함수의 내부를 확인해보면
- A.to(B) 인 경우 Pair(a, b) 를 반환한다.
- map 의 원소를 저장할 때, Pair 를 저장할 수 있으므로, 위의 코드를 사용하여 Pair값을 map 에 저장할 수 있었다.
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
- 중위 (infix) 함수는 파라미터가 한개인 경우, 확장함수를 깔끔한 구문으로 사용할 수 있다.
fun main() {
val map = mapOf<Int, String>(1 key_val "one", 2.key_val("two"))
}
infix fun <A, B> A.key_val(that: B) : Pair<A, B> = Pair(this, that)
6. 3중따옴표를 이용한 정규식에서는 역슬래시(\) 를 제외하고는 이스케이프(\\) 할 필요가 없다.
7. 로컬함수를 이용하여 코드를 더 깔끔하게 유지하고, 중복을 제거할 수 있다.
- 로컬 함수는 함수 내에서 함수를 사용하는 방식이다.
- 로컬함수는 바깥 함수의 파라미터에 접근 가능하다.
- 자바에서는 private 메소드로 계속 추출하여 코드를 이해하기 어려울 수 있는 점을 코틀린에서는 로컬 함수를 통해 해결했다.
class Person (
val name: String,
val phone: String
)
fun validatePerson(person: Person): Boolean {
fun validateName() = person.name.length in 2..4
fun validatePhone() = person.phone.matches("""^\d{2,3}-\d{3,4}-\d{4}${'$'}""".toRegex())
return validateName() && validatePhone()
}
fun main() {
val p = Person("홍길동", "010-1234-1234")
assertTrue(validatePerson(p))
}
- 위의 코드를 Person 에 대한 확장함수로 바꾼 뒤, 로컬함수로도 사용할 수 있다.
class Person (
val name: String,
val phone: String
)
fun Person.validatePerson(): Boolean {
fun validateName() = name.length in 2..4
fun validatePhone() = phone.matches("""^\d{2,3}-\d{3,4}-\d{4}${'$'}""".toRegex())
return validateName() && validatePhone()
}
fun main() {
val p = Person("홍길동", "010-1234-1234")
p.validatePerson()
}
'책 정리 > Kotlin IN ACTION' 카테고리의 다른 글
4. 클래스, 객체 인터페이스 (0) | 2021.09.10 |
---|---|
2. 코틀린 기초 (0) | 2021.08.28 |
1. 코틀린이란 무엇이며, 왜 필요한가? (0) | 2021.08.28 |