[Kotlin] 새차원의 코틀린 강좌(5)

새차원의 코틀린 강좌 - Packages, Return and Jumps


패키지
  • 소스 파일은 패키지 선언으로 시작됨
  • 모든 컨텐츠(클래스, 함수, …)는 패키지에 포함됨
  • 패키지를 명세하지 않으면 이름이 없는 기본 패키지에 포함됨 → 디폴트 패키지에 포함되므로, 다른 파일에서도 자동으로 import 되어 사용 가능해짐.
1
2
3
4
5
6
7
8
9
10
package foo.bar

fun baz() {}

class Goo {}

fun main(args: Array<String>) {
foo.bar.baz()
foo.bar.Goo()
}



기본 패키지
  • 기본으로 import되는 package
  • 플랫폼 별로 import 되는 package도 다른 부분이 있음
1
2
3
4
5
6
7
8
kotlin.*
kotlin.annotation.*
kotlin.collections.*
kotlin.comparisons.* (since 1.1)
kotlin.io.*
kotlin.ranges.*
kotlin.sequences.*
kotlin.text.*
1
2
3
4
5
6
JVM:
java.lang.*
kotlin.jvm.*

JS:
kotlin.js.*



imports
  • 기본으로 포함되는 패키지 외에도, 필요한 package 들을 직접 import 할 수 있음
1
2
3
4
5
6
7
8
9
// Bar 1개만 import
import foo.Bar

// 'foo' 패키지에 모든 것을 import
import foo.*

// foo.Bar
// bar.Bar 이름이 충돌나는 경우 'as' 키워드로 로컬 리네임 가능
import bar.Bar as bBar



3가지 Jump 표현식
  • return : 함수나 익명 함수에서 반환
1
2
3
4
fun sum(a: Int, b: Int): Int {
println("a: $a, b: $b")
return a + b
}


  • break : 루프를 종료 시킴
1
2
3
4
for (x in 1..10) {
if (x > 2) break
println("x: $x")
}


  • continue : 루프의 다음 단계로 진행
1
2
3
4
for (x in 1..10) {
if (x < 2) continue
println("x: $x")
}



Label로 break, continue
  • 레이블 표현 : label@, abc@, fooBar@
    • 식별자 + @ 형태로 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 바깥 for 문까지 종료시킬 수 있다
loop@ for (i in 1..10) {
println("--- i: $i ---")

for (j in 1..10) {
println("j: $j")
if (i + j > 12) {
break@loop
}
}
}

loop@ for (i in 1..10) {
println("--- i: $i ---")

for (j in 1..10) {
if (j < 2) {
continue@loop
}
println("j: $j")
}
}



Label로 return
  • 코틀린에서 중첩될 수 있는 요소들
    • 함수 리터럴 (function literals)
    • 지역함수 (local function)
    • 객체 표현식 (object expression)
    • 함수 (functions)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
val ints = listOf(0, 1, 2, 3)

ints.forEach(fun(value: Int) { // 익명함수
if (value == 1) return // 현재 함수만 종료됨
print(value)
})
print("END")
// 출력값 : 023END


ints.forEach { // 람다함수
if (it == 1) return // 상위 함수까지 모두 종료됨
print(it)
}
print("END")
// 출력값 : 0



람다식에서 return 시 주의사항
  • 람다식에서 return 시 nearest enclosing 함수가 return 됨
  • 람다식만 return 하려면 label 을 이용해야함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
val ints = listOf(0, 1, 2, 3)

ints.forEach { // 람다함수
if (it == 1) return // 상위 함수까지 모두 종료됨
print(it)
}
print("END")
// 출력값 : 0

ints.forEach label@ {
if (it == 1) return@label
print(it)
}
print("END")
// 출력값 : 023END



암시적 레이블
  • 람다식에서만 return 하는 경우 label 을 이용해서 return 해야 함
  • 직접 label 을 사용하는 것보다 암시적 레이블이 편리함
  • 암시적 레이블은 람다가 사용된 함수(ex. forEach)의 이름과 동일
1
2
3
4
5
6
ints.forEach {
if (it == 1) return@forEach
print(it)
}
print("END")
// 출력값 : 023END



레이블 return 시 값을 반환할 경우
  • return@label 1 형태로 사용
  • return + @label + 값
1
2
3
4
5
6
7
8
fun foo(): List<String> {
var ints = listOf(0, 1, 2, 3)
val result = ints.map {
if (it == 0) return@map "zero" // return at named label
"number $it" // expression returned from lambda
}
return result
}

- 출력 : [zero, number 1, number 2, number 3]

-> print(List) 해도 그냥 출력된다. 자바는 Arrays.toString 이런 메서드 사용했어야 됐는데 코틀린 너무 편한것같다.

아래는 IDE 에서 바꿔준 코드. 변수(result)는 return 에서만 사용되므로 inline 으로 만드는게 좋다는 메시지가 나와서 바꿔준다.

1
2
3
4
5
6
7
fun foo2(): List<String> {
val ints = listOf(0, 1, 2, 3)
return ints.map {
if (it == 0) return@map "zero" // return at named label
"number $it" // expression returned from lambda
}
}


출처 : 새차원의 코틀린 강좌 https://www.inflearn.com/course/%EC%BD%94%ED%8B%80%EB%A6%B0-%EA%B0%95%EC%A2%8C-%EC%83%88%EC%B0%A8%EC%9B%90/

Share