[Kotlin Tutorial] 함수 정의하고 호출하기 #2
참조 : Kotlin in Action
3.4. Working with collections: Varargs, Infix calls, and Library support
3.4.1. Extending the Java collections API
-
val strings: List<String> = listOf(“first”, “second”, “thrid”)
strings.last()
val numbers: Collection<Int> = setOf(1, 14, 2)
numbers.max()
last 와 max 는 extension 이다.
이 외에도 많이 있으니 IDE 의 code completion 을 잘 활용해보시라~
3.4.2. Varargs: functions that accept an arbitrary number of arguments
-
fun listOf<T>(vararg values: T): List<T>{ … }
Java 에서 … 으로 쓰던 녀석 대신 확실하게 vararg 라는 키워드를 써준다
형태는 array 가 된다
-
Spread operator 라는 게 있다
fun main(args: Array<String>){
val list = listOf(“args: “, *args) // args unpack 된다, array 를 concat 할 때 좋다
}
3.4.3. Working with pairs: infix calls and destructuring declarations
-
infix call 이란 method name 다음에 바로 parameter 를 쓰는 방식을 말한다.
to(“one”) // regular call
to “one” // infix call
-
infix call 은 1개의 param 을 받는 함수면 일반 function 던 extension function 이던 다 사용할 수 있다.
function 이 infix notation 으로 쓸 수 있도록 하려면 infix modifier 를 추가해야 한다.
infix fun Any.to(other: Any) = Pair(this, other)
( Any 에 대해서는 나중에 배운답니당, Object 같은 녀석이에요 )
-
Pair 를 이용해서 2개의 var 를 한번에 init 할 수도 있다.
val (number, name) = 1 to “one”
요런 녀석을 destructuring declaration 이라고 한다.
이 destructuring declaration 은 map 의 iteration 등에도 사용된다.
for ( (index, element) in collection.withIndex() ){
println(“$index: $element”)
}
-
to 는 extension function 이다.
그런데 이 녀석은 generic receiver 라서 어떤 type 이든 다 받아줄 수 있다.
1 to “one”, “one” to 1, list to list.size() 등 다 된다
3.5. Working with strings and regular expressions
3.5.1. Splitting strings
-
Java 의 split method 는 정말 많이 사용된다.
그러나 param 으로 regular expression 을 받기 때문에 사람들이 가장 많이 하는 실수가 “.” 으로 split 하는 것이다.
"12.345-6.A”.split(“.”) // 결과는 empty array, . 은 regex 로 any char
이런 혼란을 막기 위해 String 에 toRegex() extension 이 추가되었고, 이 녀석의 type 은 Regex 이다.
split 은 String 과 RegEx 두가지 type 을 다루는 녀석들로 각각 구현되었다.
"12.345-6.A".split('.")
"12.345-6.A".split("\\.|-".toRegEx()))
여러 개의 delimiter 를 사용할 수 있는 녀석(varargs 형태)도 정의되었다. ( Auto complete 을 잘 이용해보세영~ )
3.5.2. Regular expressions and triple-quoted strings
-
substringBeforeLast("/"), substringAfterLast("/") 등의 extension 도 생겼다.
url 을 parsing 할 때 좋다.
-
fun parsePath(path: String){
val regex = “””(.+)/(.+)\.(.+)”””.toRegex() // toRegex 를 할 때 오히려 일반 . 을 escape 해야 한다
val matchResult = regex.matchEntire(path)
if(matchResult != null){
val (directory, filename, extension) = matchResult.destructured
println(“Dir: $directory, name: $filename, ext: $extension”)
}
}
“””regExp””” 를 사용하면 escape 가 필요없다.
\\. 대신 \. 을 쓰면 된다. ( 실제 . 표현할 경우 )
desturctured 함수를 통해 destructuring declaration 도 가능하다
3.5.3. Multiline triple-quoted strings
-
“”” 는 escape character 방지는 물론 line break 가 있는 text 를 쉽게 쓸 수 있게 한다.
\n 같은 것도 필요 없고, \ 도 escape 할 필요도 없다
val kotlinLogo = “””| //
.|//
.|/ \”””
println(kotlinLogo.trimMargin(“.”)) // . 을 기준으로(포함해서) preceding margin 을 제거한다
-
“”” 안에는 string template 도 쓸 수 있다.
그럼 $ 는 어떻게 표시할 것인가?
val price = “””${‘$’}99.9””” // 이 녀석은 불행히도 이렇게 써야 한다
val a = 3
println("""$a""") // 3
println("""$$a""") // $3
println("""${'$'}a""") // $a
-
이 multiline triple-quoted string 은 test 할 때 big string 을 그냥 복붙해서 사용할 때 좋다.
그리고 trimMargin 과 조합해서 사용하면 더 좋다
-
extension function 은 이렇게 강력하다.
대부분의 Kotlin lib 은 Java lib 에 extension 을 한 것이고,
Anko 라는 녀석은 android lib 을 extension 한 것이다.
그 외에도 Spring 같은 녀석들도 extension 을 사용했고, 다른 3rd party extension 도 많다.
3.6. Making your code tidy: local functions and extensions
-
Function extraction 을 하다보면 코드를 이해하는 데 어려울 수 있고,
inner class 를 만들어 그곳에 해당 function 들을 넣다보면 구조에 대한 유지보수가 또 들어간다.
이 때 쓰는 것은 local function 이다.
class User(val id: Int, val name: String, val address: String)
fun saveUser(user: User){
if( user.name.isEmpty()) ){
throw IllegalArgumentException(“Can’t save user ${user.id}: empty Name”)
}
if( user.address.isEmpty()){
throw IllegalArgumentException(“Can’t save user $user.id}: empty Address”)
}
// save user to DB
}
class User(val id: Int, val name: String, val address: String)
fun saveUser(user: User){
fun validate(value: String, fieldName: String){
if( value.isEmpty() ){
throw IllegalArgumentException(“Can’t save user ${user.id}: empty $fieldName”)
}
}
validate(user.name, “Name”)
validate(user.address, “Address”)
}
local function 은 enclosing function 의 모든 variable 과 parameter 를 사용할 수 있다.
-
local function 을 사용할 때는 deep nested 가 되지 않도록 해야 한다는 것.
3.7. Summary
-
Kotlin 은 자신만의 collection 을 정의하지 않고 Java 의 것을 사용하면서 extension 으로 API 를 더 강화했다.
-
Default value 를 잘 사용하면 overload function 을 많이 줄일 수 있다.
그리고 named-argument 는 훨씬 가독성 좋게 코드를 짤 수 있게 해준다.
-
function 과 property 는 file 에 바로 쓰일 수 있다. ( class 안이 아닌 top level )
이 녀석들은 static function, static variable 로 작동한다.
-
extension function 은 소스코드 유무 상관없이 존재하는 모든 class 를 확장할 수 있게 해준다.
물론 runtime overhead 는 없다.
-
infix call 은 single arg 일 경우 쓸 수 있는데 operation 같은 형태로 더 깔끔하게 코드를 쓸 수 있게 해준다.
-
Kotlin 은 string 을 다루는 여러 편리한 함수들을 제공한다.
그리고 이는 일반 string 과 regex string 모두 지원한다
-
triple-quoted string 은 읽기 어려운 escaping 관련된 코드와 string concatenation 을 방지해준다.
-
Local function 은 code 의 구조를 더 깔끔하게 가져가면서 중복코드를 줄이는 데 기여할 수 있다.
'프로그래밍 놀이터 > Kotlin, Coroutine' 카테고리의 다른 글
[Kotlin Tutorial] 클래스, objects, 그리고 인터페이스 #2 (0) | 2017.08.14 |
---|---|
[Kotlin Tutorial] 클래스, objects, 그리고 인터페이스 #1 - Chap4. Classes, objects, and interfaces (0) | 2017.08.11 |
[Kotlin Tutorial] 함수 정의하고 호출하기 #1 - Chap 3. Defining and calling functions (0) | 2017.08.03 |
[Kotlin Tutorial] Kotlin 기초 #2 - Chap2. Kotlin basics (0) | 2017.07.25 |
[Kotlin Tutorial] Kotlin 기초 #1 - Chap2. Kotlin basics (0) | 2017.07.25 |
댓글