Posts 코틀린의 함수 (Kotlin In Action - Dmitry Jemerov, Svetlana Isakova)
Post
Cancel

코틀린의 함수 (Kotlin In Action - Dmitry Jemerov, Svetlana Isakova)

본 포스팅은 Kotlin In Action - Dmitry Jemerov, Svetlana Isakova 책을 읽고, 기록하기 위한 용도로 작성되었습니다. 이 책의 대상 독자는 어느 정도 자바를 알고 있는 개발자를 대상으로 합니다. 서버 개발자나 안드로이드 개발자, JVM에서 실행되는 프로젝트를 구축중인 개발자들이라면 이 책이 도움이 될 것입니다.

코틀린의 함수

컬렉션

1
2
3
4
5
6
7
8
// hashset
var set = hashSetOf(1, 3, 27)

// list
var list = arrayList(1, 3, 27)

//map
var map = hashMapOf(1 to "one", 3 to "three", 27 to "twenty-seven")

위에서 사용한 객체들은 모두 java.util에 속하는 객체들입니다. 즉, 코틀린에서 제공하는 컬렉션 프레임워크는 자바로부터 온 것인데, 코틀린만의 컬렉션을 만들지 않은 이유는 자바 코드와 상호작용하기 쉽도록 설계했기 때문이라고 합니다.

함수를 호출하기 쉽게

kotlinlang - functions

(1) 생성자를 오버로딩할 필요가 없음

  • 알아서 인자를 하나씩 제거하며 생성자를 만들어 주기 떼문에 생성자가 없다거나 파라미터 갯수가 틀리다는 오류로부터 자유로워요!!

  • 파라미터 입력 시, 필드명도 입력할 수 있어서 가시성이 좋아시면서 혼동이 줄어들고 몇 번째 파라미터 값이 잘못되었다는 오류는 이제 그만!! 볼 수 있습니다.

1
2
3
fun foo(bar: Int = 0, baz: Int) { /*...*/ }

foo(baz = 1) // bar는 디폴드 값인 0이 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fun reformat(str: String,
             normalizeCase: Boolean = true,
             upperCaseFirstLetter: Boolean = true,
             divideByCamelHumps: Boolean = false,
             wordSeparator: Char = ' ') {
/*...*/
}

// 차례대로 입력해도 되고,
reformat(str, true, true, false, '_')

// 필드명과 함께 차례대로 입력해도 되고,
reformat(str,
    normalizeCase = true,
    upperCaseFirstLetter = true,
    divideByCamelHumps = false,
    wordSeparator = '_'
)

// 넣고 싶은 필드값만 지정해서 입력해도 됩니다.
reformat(str, wordSeparator = '_')

(2) 함수를 클래스로 감쌀 필요가 없음

코틀린에서는 함수를 선언하기 위해서 클래스를 만들 필요가 없습니다.

1
2
3
package some.package

fun someFunction(...) { ... }

자바로 본다면, 코틀린 컴파일러가 생성하는 클래스의 이름은 함수가 들어있던 소스 파일의 이름과 대응됩니다.

만약 some.kt에 위의 내용이 적혀 있었다면, 자바 소스 코드로 볼 때, 다음과 같습니다.

1
2
3
4
5
package some.package;

public class SomeKt {
  public static someFunction(...) { ... };
}

(3) 확장 함수와 확장 프로퍼티

kotlinlang - Extensions

확장 함수는 자바에서 상속을 받은 후, 오버라이드 하여 사용하는 것과 같은 개념입니다. 하지만 상속을 받거나 데코레이터 같은 디자인 패턴이 필요하지 않습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
open class Shape

class Rectangle: Shape()

fun Shape.getName() = "Shape"

fun Rectangle.getName() = "Rectangle"

fun printClassName(s: Shape) {
    println(s.getName())
}    

printClassName(Rectangle())

이 코드는 “Shape”를 출력합니다. Rectangle이 Shape 타입으로 만들어졌기 때문에, Shape의 getName()이 실행됩니다.

다음 예제에서 다시 보면,

1
2
3
4
5
6
7
class Example {
    fun printFunctionType() { println("Class method") }
}

fun Example.printFunctionType() { println("Extension function") }

Example().printFunctionType()

결과 값이 “Extension function”로 나타날 것 같지만, 실제로는 “Class method”가 출력됩니다. “kotlinlang.org”에서는 이것을 “member always wins.” 이라고 하는데요, 클래스가 가지고 있는 함수가 항상 우위를 가집니다.

  • 클래스에 멤버함수가 있고,
  • 확장함수와 멤버함수가 이름이 같고,
  • 확장함수와 멤버함수가 같은 파라미터를 가지면,

-> “member always wins.”

다음과 같이 다른 파라미터 값을 가지는 경우라면,

1
2
3
4
5
6
7
class Example {
    fun printFunctionType() { println("Class method") }
}

fun Example.printFunctionType(i: Int) { println("Extension function") }

Example().printFunctionType(1)

“Extension function”이 출력됩니다. Int 값의 파라미터를 가진 확장함수가 실행이 된 것이죠. ✨ 확장 함수를 만들 때는, 멤버 함수가 더 우선되어서 실행된다는 것을 주의해야 겠습니다.

문자열 다루기

(1) 문자열 나누기

1
2
3
4
5
6
7
8
// '.'을 이스캐이프 하는 경우
>>> println("13.58-5".split("\\.|-".toRegex))

// 여러 문자열을 지정하는 경우
>>> println("13.58-5".split(".","-"))

// 두가지 모두 같은 결과값을 볼 수 있습니다.
[13, 58, 5]

(2) 문자열 함수들 (ex 파일 경로명 분리하기)

kotlinlang - text

substringBeforeLast()와 substringAfterLast()를 잘 사용하면, 정규식을 사용하지 않고 파일경로와 파일명, 확장자를 쉽게 나눌 수 있습니다.

  • path : “/user/dir/folder/a/test.txt”
1
2
3
4
5
6
7
8
9
// 1. "/"를 기준으로 나눔
fun parsePath(path: String) {
  var dir = path.substringBeforeLast("/")
  var fileAndType = path.substringAfterLast("/")

  // 2. "."를 기준으로 나눔
  var filename = fileAndType.substringBeforeLast(".")
  var fileType = fileAndType.substringAfterLast(".")
}

3중 문자열

1
2
3
4
5
6
7
8
9
10
11
12
13
val text = """|  ☆
             >| ☆
             >| *.
             >|   +
             >| .*"""

>>> println(text.trimMargin(">")) // trimMargin: 특별한 문자를 포함한 직전의 공백을 제거
// 출력결과는 아래와 같습니다 👍👍
|  
| 
| *.
|   +
| .*

3중 문자열은 역슬래시”"를 이용한 이스케이프를 할 필요가 없습니다. 예를 들어, 경로를 나타낼 때 “\user\dir\…“과 같이 나타내야 했습니다. 하지만 3중 문자열을 사용하면 간단히 나타낼 수 있습니다.

1
2
var path = """C:\Users\dir\folder\test.txt"""
// 👍👍👍👍👍

불필요한 코드를 줄이기 위해서 노력했다고 하던데 확실히 코드량도 그렇지만 구현하는 방법 자체가 깔끔하다는 생각이 듭니다. 조금 낯설어서 적응을 해야겠지만요. :-)

This post is licensed under CC BY 4.0 by the author.

코틀린이란? (Kotlin In Action - Dmitry Jemerov, Svetlana Isakova)

리액트 네이티브로 카카오 로그인 구현하기 (2021.11)

Comments powered by Disqus.