JiwonDev

#3 Nullable Type๊ณผ ํ•จ์ˆ˜, ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ

by JiwonDev

NullPointerExecption์€ ๊ณผ๊ฑฐ๋ถ€ํ„ฐ ์ง€๊ธˆ๊นŒ์ง€ ๊ฐœ๋ฐœ์ž๋ฅผ ๊ดด๋กญํžˆ๋Š” ์˜ˆ์™ธ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

์ฝ”ํ‹€๋ฆฐ์€ ์ด๋ฅผ ์•Œ๊ณ  ์žˆ๊ธฐ์—, ์• ์ดˆ์— [ Null์ด ๊ฐ€๋Šฅํ•œ ํƒ€์ž… ]๊ณผ [ Null์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ธฐ๋ณธํƒ€์ž… ]์„ ๊ตฌ๋ถ„ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

 

๐Ÿ’ญ Nullable Type (?=)

๊ธฐ๋ณธ์ ์œผ๋กœ ์ฝ”ํ‹€๋ฆฐ์€ ๋ณ€์ˆ˜์˜ null ๋Œ€์ž…์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ์•„๋ž˜์˜ ์ฝ”๋“œ๋Š” ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

val s1: String = null // compile error: Null can not be a value of a non-null type String

 

๋งŒ์•ฝ null์„ ํ—ˆ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, Nullable Type์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.์ด๋Š” Type? ๋ฌธ๋ฒ•์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

val s2: String? = null // OK

 

  • ์ด๋Ÿฌํ•œ ๋„ ํƒ€์ž… ๊ตฌ๋ถ„ ๋•๋ถ„์— null ์ฒดํฌ๊ฐ€ ํ•„์š”ํ•œ์ง€ ์—ฌ๋ถ€๋ฅผ ์‰ฝ๊ฒŒ ํ™•์ธํ•   ์ˆ˜ ์žˆ๋‹ค.

 

  • ๋งŒ์•ฝ Nullable ํƒ€์ž…์„ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด, ๋ฐ˜๋“œ์‹œ null์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.
    ์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์ด ?. ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Safe Access๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
foo?.bar() // ๋งŒ์•ฝ foo๊ฐ€ null์ด๋ผ๋ฉด, ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
foo?.get().bar() // ์ด๊ฒƒ๋„ ๋˜‘๊ฐ™์ด ์ฒ˜๋ฆฌ๋œ๋‹ค.

NullableType์„ ๊ธฐ๋ณธํƒ€์ž…์ฒ˜๋Ÿผ ์กฐํšŒํ•˜๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. 

 

  • ๋‹น์—ฐํ•œ๊ฑฐ์ง€๋งŒ Safe access๋กœ ๊ฐ€์ ธ์˜จ ๊ฐ’์€ null์ด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๊ธฐ๋•Œ๋ฌธ์—, Nullable ํƒ€์ž…( Int? )์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค. 
    ์ฐธ๊ณ ๋กœ Safe access๋ฅผ nullable ํƒ€์ž…์ด ์•„๋‹Œ ๊ณณ์— ์‚ฌ์šฉํ•  ์ˆ˜๋Š” ์žˆ์œผ๋‚˜, ๊ตณ์ด ๊ทธ๋ ‡๊ฒŒ ์‚ฌ์šฉํ•  ์ด์œ ๋Š” ์—†๋‹ค.

( Int )๊ฐ€ ์•„๋‹Œ ( Int? ) ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค.

 

  • Elvis operator๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋งˆ์น˜ Js์ฒ˜๋Ÿผ null๊ฐ’์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

null์ผ๋•Œ ๋ฐ˜ํ™˜ํ•  ๊ธฐ๋ณธ ๊ฐ’์„ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

 

  • ์ž๋ฐ”์ฒ˜๋Ÿผ null์ผ ๋•Œ NPE ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  ์‹ถ๋‹ค๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด ๋Š๋‚Œํ‘œ 2๊ฐœ (!!)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
    ์ด๋ฅผ Not-null assertion์ด๋ผ๊ณ  ํ•œ๋‹ค.

s?.get() ๊ณผ ์‚ฌ์šฉ๋ฒ•์ด ๋น„์Šทํ•˜๋‹ค. null์ด๋ผ๋ฉด NullPointerException์ด ๋ฐœ์ƒํ•œ๋‹ค.

 

  • Nullable ๋ฌธ๋ฒ• ( ?  ?.  ?:  !!  !!.) ์„ ์‚ฌ์šฉํ•  ๋•Œ, ์˜๋ฏธ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜์ž. ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ๋‹ค

์šฐ์„  ์ˆœ์œ„๋ฅผ ์™ธ์šฐ์ง€๋ง๊ณ  ํ—ท๊ฐˆ๋ฆด๋งŒํ•œ ์ฝ”๋“œ๋Š” ๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ช…์‹œ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ์ž.

 

 


๐Ÿ’ญ Nullable Type์˜ ๋™์ž‘๋ฐฉ์‹

์ฝ”ํ‹€๋ฆฐ์—์„œ์˜ Nullable Type์€ ์ž๋ฐ”์˜ @NotNull, @Nullable ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค.

์ฆ‰ ์ปดํŒŒ์ผ ํƒ€์ž„์—์„œ ๊ฑธ๋Ÿฌ์ง€๋Š”๊ฑฐ์ง€, ์‹ค์ œ ๋ฐ”์ดํŠธ์ฝ”๋“œ์ƒ์—์„œ๋Š” ๊ทธ๋ƒฅ ์ผ๋ฐ˜ ๊ฐ์ฒด์™€ ๋™์ผํ•˜๋‹ค. Optional์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ฆ‰ ๋Ÿฐํƒ€์ž„์ƒ์— ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์—†๋‹ค.

 

์ด๋ฅผ ์–ธ๊ธ‰ํ•˜๋Š” ์ด์œ ๋Š”, ๋งˆ์น˜ ์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” Optional.get()์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์ฝ”ํ‹€๋ฆฐ์˜ NullableType์€ ์–ธ์–ด ์ฐจ์›์˜ ํŽธ์˜ ๊ธฐ๋Šฅ์ด๋‹ค. ์ปดํŒŒ์ผ ์ดํ›„ ๋Ÿฐํƒ€์ž„์—๋Š” ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ์ด ์—†๋Š”๊ฑธ ์ธ์ง€ํ•˜์ž.

Nullable ํƒ€์ž…์„ ?. ์œผ๋กœ ์กฐํšŒํ•˜์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

 


๐Ÿ’ญ as, as? (Safe Cast)

์ฝ”ํ‹€๋ฆฐ์€ ์ •์ ํƒ€์ž…์–ธ์–ด์ด๋‹ค. ์ปดํŒŒ์ผ ์‹œ์ ์— ๋ชจ๋“  ํƒ€์ž…์ด ๊ฒฐ์ •๋œ๋‹ค.

ํƒ€์ž…์ถ”๋ก ์„ ์ œ๊ณตํ•ด์ค˜์„œ ์ง์ ‘ ํƒ€์ž…์„ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋˜์ง€๋งŒ, ํ•„์š”ํ•˜๋‹ค๋ฉด as ๋ฅผ ์ด์šฉํ•ด์„œ ๋ช…์‹œ์ ์ธ ์บ์ŠคํŒ…์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ณดํ†ต์€ ์ƒ๋žตํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

 

๋งŒ์•ฝ ํŠน์ • ํƒ€์ž…์„ ๊ฐ•์ œํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด Safe Casting ๋ฌธ๋ฒ•์ธ as? ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•ด๋‹น ํƒ€์ž…์ด ์•„๋‹ˆ๋ฉด null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์บ์ŠคํŒ…์„ ์•„์˜ˆ ์‹œ๋„ํ•˜์ง€์•Š๊ณ , ๋ฐ”๋กœ null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

์ฝ”ํ‹€๋ฆฐ์—๋Š” nullable ํƒ€์ž…์ด ๋ณ„๋„๋กœ ์กด์žฌํ•œ๋‹ค. Safe Casting์„ ์ด์šฉํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

var s:String = "3"

println(s as Int?) // ์บ์ŠคํŒ… ์‹œ๋„. (Int?) s โžก ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ ๋ฐœ์ƒ: ClassCastException

println(s as? Int) // OK ์บ์ŠคํŒ…์„ ์‹œ๋„ํ•˜์ง€ ์•Š๊ณ , ๋ฐ”๋กœ null์„ ๋ฐ˜ํ™˜ํ•จ
println(s as? Int?) // OK ์บ์ŠคํŒ…์„ ์‹œ๋„ํ•˜์ง€ ์•Š๊ณ , ๋ฐ”๋กœ null์„ ๋ฐ˜ํ™˜ํ•จ

 

 


๐Ÿ’ญ ์ต๋ช…ํ•จ์ˆ˜, Lambda ๋žŒ๋‹ค, It ํ‚ค์›Œ๋“œ

JDK8์—์„œ ๋žŒ๋‹ค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋งŒํผ, ์ฝ”ํ‹€๋ฆฐ ๋˜ํ•œ ํ•จ์ˆ˜ํ˜• ๋ฌธ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค.

์ถ”๋ก ์ด ๊ฐ€๋Šฅํ•œ ๋ถ€๋ถ„์€ ์ƒ๋žต์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

// 0๋ณด๋‹ค ํฐ ๊ฐ’์ด ํ•˜๋‚˜๋ผ๋„ ์žˆ๋‹ค๋ฉด true
list.any( { i: Int -> i>0 } )
list.any( { i: Int -> i>0 } )
list.any() { i: Int -> i>0 } ) // 1๏ธโƒฃ ๋žŒ๋‹ค๊ฐ€ ๋งˆ์ง€๋ง‰ ์ธ์ž๋ผ๋ฉด, ์ด๋ ‡๊ฒŒ ๊ตฌ๋ถ„ํ•ด์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅ
list.any { i: Int -> i>0 } // 2๏ธโƒฃ ๋žŒ๋‹ค ์ด์™ธ์˜ ์ธ์ž๊ฐ€ ์—†๋‹ค๋ฉด, method() ๊ด„ํ˜ธ๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Œ.
list.any { i -> i>0 } // 3๏ธโƒฃ ์ฝ”ํ‹€๋ฆฐ์€ ํƒ€์ž…์ถ”๋ก ์ด ๊ฐ€๋Šฅํ•˜๊ธฐ์—, ํƒ€์ž…๋„ ์ƒ๋žตํ•ด๋„๋จ

 

๋งŒ์•ฝ ํ•จ์ˆ˜์˜ ์ž…๋ ฅ๊ฐ’์ด 1๊ฐœ ( x -> x+1) ๋ผ๋ฉด, it ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งˆ์น˜ ์ž๋ฐ”์˜ this์™€ ๋Š๋‚Œ์ด ๋น„์Šทํ•˜๋‹ค.

list.any { i -> i>0 } 
list.any { it>0 }

 

๋žŒ๋‹ค์‹์—๋Š” return์ด ์ œ๊ณต๋˜์ง€ ์•Š๋Š”๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ์‚ฌ์šฉํ•œ ์‹์ด return ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

intelliJ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌด์—‡์ด ๋ฐ˜ํ™˜๊ฐ’์ธ์ง€ ์‰ฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๋‹ค. (^any)

๐Ÿงจ ๋งˆ์ง€๋ง‰์œผ๋กœ ์‚ฌ์šฉํ•œ ํ‘œํ˜„์‹์ด ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ์ด๋ฅผ ์กฐ์‹ฌํ•˜์ž.

๋งŒ์•ฝ if(~) return ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, return@flatMap ๊ฐ™์€ ๋ณ„๋ช…์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ๊ธ€ ์•„๋ž˜์—์„œ ์ถ”๊ฐ€๋กœ ์„ค๋ช…ํ•œ๋‹ค.

list.flatMap {
    if (it == 0) listOf<Int>() // ๊ทธ๋ƒฅ ๋ฒ„๋ ค์ง. ๋žŒ๋‹ค ๋ฐ˜ํ™˜๊ฐ’์ด ์•„๋‹˜ โŒ
    listOf(it, it) // ๋งˆ์ง€๋ง‰ ํ‘œํ˜„์‹. ๋žŒ๋‹ค ๋ฐ˜ํ™˜๊ฐ’์ด ๋งž์Œ โญ•
}

list.flatMap {
    if (it == 0) listOf<Int>() // if-else ๋งˆ์ง€๋ง‰ ํ‘œํ˜„์‹. ๋ฐ˜ํ™˜๊ฐ’์ด ๋งž์Œ โญ•
    else listOf(it, it) // if-else ๋งˆ์ง€๋ง‰ ํ‘œํ˜„์‹. ๋ฐ˜ํ™˜๊ฐ’ ๋งž์Œ โญ•
}

 

์ฝ”ํ‹€๋ฆฐ์€ Python์ด๋‚˜ JS์ฒ˜๋Ÿผ ๊ตฌ์กฐ๋ถ„ํ•ด ํ• ๋‹น(Destructuring declarations)์„ ์ง€์›ํ•œ๋‹ค.

var (a, b) = Pair(3, 4)
var (_, b) = Pair(3, 4) // ๋งŒ์•ฝ ๋‘˜ ์ค‘ ๊ฐ’ ํ•˜๋‚˜๋งŒ ํ•„์š”ํ•˜๋‹ค๋ฉด, _ ์„ ์‚ฌ์šฉํ•ด์„œ ๋ฒ„๋ฆด ์ˆ˜ ์žˆ๋‹ค.


// data class Person(val name: String, val age: Int)
val person = Person("chacha", 10)
val (name, age) = person
val (name, _) = person
println("$name, $age")

 

์ด๋ฅผ ๋žŒ๋‹ค์‹์—์„œ๋„ ๋˜‘๊ฐ™์ด ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

val map = mapOf<Int, String>(1 to "one", 2 to "two", 3 to "Three")

map.mapValues { item -> "${item.key} : ${item.value}" }
map.mapValues { (key, value) -> "$key : $value" }

 

์ฐธ๊ณ ๋กœ it ํ‚ค์›Œ๋“œ๋Š” ๊ฐ ์‹๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒŒ ์‚ฌ์šฉ๋œ๋‹ค. ์•„๋ž˜ 3๊ฐœ์˜ ์ฝ”๋“œ๋Š” ๊ฐ™์€ ๋™์ž‘์„ ํ•œ๋‹ค.

3๊ฐœ๋Š” ๊ฐ™์€ ๋™์ž‘์„ ํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.

 

์œ„ ์˜ˆ์ œ์ฒ˜๋Ÿผ ์–ต์ง€๋กœ It์„ ์‚ฌ์šฉํ•ด์„œ ํ•œ์ค„๋กœ ๋งŒ๋“ค์ง€ ๋ง๊ณ , ์ฑ…์ž„์„ ๋‚˜๋ˆ  ์ฝ๊ธฐ ์ข‹๊ฒŒ ๋ฆฌํŒฉํ† ๋ง ํ•ด์„œ ์‚ฌ์šฉํ•˜์ž.

 

 


๐Ÿ’ญ ํ•จ์ˆ˜ํ˜• ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ( filter, map, reduce...)

JDK8์—์„œ ์ œ๊ณตํ•˜๋Š” filter, map, sum๋“ฑ์˜ ํ•จ์ˆ˜ํ˜• ๋ฉ”์„œ๋“œ๋Š” ์ „๋ถ€ ์ œ๊ณตํ•œ๋‹ค.

๋ฌธ๋ฒ•๋งŒ ์‚ด์ง ๋‹ค๋ฅผ ๋ฟ, ์ž๋ฐ”์™€ ์‚ฌ์šฉ๋ฒ•์€ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š๋‹ค.
์ฝ”ํ‹€๋ฆฐ ํ™•์žฅํ•จ์ˆ˜๋กœ ๋” ํ’๋ถ€ํ•œ ํ•จ์ˆ˜๋“ค์„ ์ œ๊ณตํ•ด์ฃผ๋‹ˆ ํ•„์š”ํ•˜๋ฉด ์ฐพ์•„๋ณด๋„๋ก ํ•˜์ž.

์ฐธ๊ณ ๋กœ ์ฐพ๋Š” ๊ฐ’์ด ์—†๋‹ค๋ฉด NoSuchElementException ๋ฐœ์ƒ. (null์„ ๋ฐ˜ํ™˜ ๋ฐ›๊ณ ์‹ถ๋‹ค๋ฉด ~OrNull ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ž)
partition, groupBy

 

associate, associateBy

 

zip, zipWithNext

 

flattern, flatmap

 


๐Ÿ’ญ ํ•จ์ˆ˜๋ฅผ ์ผ๊ธ‰์‹œ๋ฏผ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ

์ฝ”ํ‹€๋ฆฐ์€ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋‚˜ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ํ•จ์ˆ˜ ํƒ€์ž…์€ python์ฒ˜๋Ÿผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์˜ํ•œ๋‹ค.

ํ•จ์ˆ˜ ํƒ€์ž…์„ ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•
์ฐธ๊ณ ๋กœ ์ž๋ฐ”์—์„œ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ๊ณผ ๋™์ž‘์ด ๊ฐ™๋‹ค.

์ฝ”ํ‹€๋ฆฐ ๋ฌธ๋ฒ•์„ ์ ์ ˆํ•˜๊ฒŒ ํ™œ์šฉํ•˜๋ฉด, ๋ณ€์ˆ˜์— ๋žŒ๋‹คํ•จ์ˆ˜๋ฅผ ํ•œ์ค„๋กœ ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

val isEven: (Int) -> Boolean = { it % 2 == 0 } // ํ•˜..ํ•˜์Šค์ผˆ?

val result: Boolean = isEven(42) // True

 

ํ•จ์ˆ˜๋ฅผ ()๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ฝ”ํ‹€๋ฆฐ์—๋Š” run ํ‚ค์›Œ๋“œ๋ฅผ ์ œ๊ณตํ•ด์ค€๋‹ค.

 

๋ฌผ๋ก  ์ฝ”ํ‹€๋ฆฐ์—์„œ๋งŒ ํ•จ์ˆ˜๋ฅผ ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ๊ณ , ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์ž๋ฐ”์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ํ•œ๋ฒˆ ์ •์˜ํ•œ ๋žŒ๋‹คํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ ๋ณ€์ˆ˜์— ๋‹ด์„ ์ˆ˜ ์—†๋‹ค.

๊ทผ๋ฐ ํฐ ์ƒ๊ด€์—†๋Š”๊ฒŒ, ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

์•„๋ž˜์— ์–ธ๊ธ‰ํ•  ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค(๋ฉค๋ฒ„ ์ฐธ์กฐ)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณต์‚ฌํ•˜๋“ฏ์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

::isEven ์€ ๋ฉค๋ฒ„์ฐธ์กฐ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. 3๋ฒˆ์งธ ์ค„๊ณผ ๊ฐ™์€ ๋™์ž‘์ด๋‹ค.
์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ๋•Œ์—๋Š”, ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜์ž


๐Ÿ’ญ ํ•จ์ˆ˜๋„ NotNull, Nullable ๋‘๊ฐœ์˜ ํƒ€์ž…์ด ์กด์žฌํ•œ๋‹ค.

๋‹น์—ฐํžˆ ๋žŒ๋‹คํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ Nullable์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

val f1: () -> Int? = { null } // ๊ฐ€๋Šฅ
f1() // ์‹คํ–‰ ๊ฐ€๋Šฅ () -> null ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋จ

 

ํ•จ์ˆ˜ ์ž์ฒด์— Nullable ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด [๋žŒ๋‹ค ํ•จ์ˆ˜] ๋Œ€์‹  [null]์„ ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค.

val f3: ( ()->Int )? = null // OK ๊ฐ€๋Šฅ
f3() // ์‹คํ–‰ ๋ถˆ๊ฐ€๋Šฅ. f3 == null ์ž„

 

์œ„์˜ 2๊ฐ€์ง€๋ฅผ ํ˜ผ๋™ํ•ด์„œ ์‚ฌ์šฉํ•˜๋‹ค๊ฐ€ ์ปดํŒŒ์ผ ์—๋Ÿฌ๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ๋Š”๋ฐ, { null } ์€ ๋„๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋žŒ๋‹คํ•จ์ˆ˜์ž„์„ ์ธ์ง€ํ•˜์ž.

val f2 = null ์€ ๋žŒ๋‹ค์˜ ๋ฐ˜ํ™˜๊ฐ’์ด ์•„๋‹ˆ๋ผ, ๋ณ€์ˆ˜ ์ž์ฒด์— null์„ ๋„ฃ๋Š”๊ฑฐ๋‹ค.

val f1: ()->Int? = {null} // ๊ฐ€๋Šฅ. ๋žŒ๋‹คํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์€ Nullable ํƒ€์ž…์ธ Int? ์ž„.
val f2: ()->Int? = null // ๋ถˆ๊ฐ€๋Šฅ. ์ปดํŒŒ์ผ์—๋Ÿฌ f2๋Š” ๊ธฐ๋ณธํƒ€์ž…์ž„

val f3: ( ()->Int )? = null // ๊ฐ€๋Šฅ. f3๋Š” Nullable ํƒ€์ž…์ž„.
val f4: ( ()->Int )? = {null} // ๋ถˆ๊ฐ€๋Šฅ. ์ปดํŒŒ์ผ ์—๋Ÿฌ ๋žŒ๋‹คํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์€ ๊ธฐ๋ณธํƒ€์ž… Int์ž„.

 


๐Ÿ’ญ Member Refernces (๋ฉ”์„œ๋“œ ์ฐธ์กฐ)

JDK8์˜ ๋ฉ”์„œ๋“œ ์ฐธ์กฐ์™€ ๊ฑฐ์˜ ๋™์ผํ•˜๋‹ค.

์ฝ”ํ‹€๋ฆฐ์—์„œ์˜ ๋ฉค๋ฒ„์ ‘๊ทผ์€ Person.age , Person.name ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ Getter, Setter๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์œ„์—๋„ ์‚ด์ง ์–ธ๊ธ‰ํ–ˆ์ง€๋งŒ, ์ฝ”ํ‹€๋ฆฐ์—์„œ ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ์ง€, ๋‚ด๋ถ€๋ฅผ ๊นŒ๋ณด๋ฉด ์ž๋ฐ”์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ• ๋•Œ์—๋Š” ๋ฉค๋ฒ„ ์ฐธ์กฐ๋ฅผ ์ด์šฉํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์— ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค๋ณด๋‹ˆ, ๊ฐ์ฒด์˜ Bound / UnBound๋ผ๋Š” ๊ฐœ๋…์ด ์ƒ๊ธด๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž

class Person(val name: String, val age: Int) { 
    fun isOlder(limit: Int) = age > limit
}
    
var jiwon = Person("Jiwon", 29)
// ์•„๋ž˜ ๋‘ ํ•จ์ˆ˜๋Š” ๋™์ผํ•˜๋‹ค. (unBound reference)
var isOld = Person::isOlder
var isOld = (Person, Int) -> { (person, limit) -> person.isOlder(limit) }

isOld(jiwon, 20)
isOld(alice, 21)

 

๋งŒ์•ฝ jiwon.isOlder() ๋ฅผ ๋ฐ”๋กœ ํ˜ธ์ถœํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์ฆ‰ Bound reference๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด this๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

// ์•„๋ž˜ ๋‘ ํ•จ์ˆ˜๋Š” ๋™์ผํ•˜๋‹ค. (Bound reference)
var isOld = this::isOlder
var isOld = (Int) -> { (limit) -> this.isOlder(limit) }

isOld(20)
isOld(21)

 

์ฐธ๊ณ ๋กœ this::method ์—์„œ this๋Š” ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.

fun getAge() = this::isOlder
fun getAge() = ::isOlder

 

๋‹ค๋งŒ ํ—ท๊ฐˆ๋ฆฌ๋ฉด ์•ˆ๋˜๋Š”๊ฒŒ, this::method๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๊ณ  ํ•ด์„œ ๋ฌด์กฐ๊ฑด bound ํ•จ์ˆ˜์ธ๊ฑด ์•„๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด ๊ทธ๋ƒฅ ํ˜„์žฌ ์Šค์ฝ”ํ”„์— ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—๋„ this::method๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

isEven์€ ๊ทธ๋ƒฅ ํ•จ์ˆ˜์ด๋‹ค. Bound/unBound๋ž‘ ์ƒ๊ด€์—†์Œ.

 

๐Ÿงจ ๋žŒ๋‹คํ•จ์ˆ˜๋Š” return ํ‚ค์›Œ๋“œ๋ฅผ ๊ทธ๋ƒฅ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

return ์€ ์–ธ์ œ๋‚˜ ํ•จ์ˆ˜(fun ํ‚ค์›Œ๋“œ)์˜ ๋ฐ˜ํ™˜์„ ์˜๋ฏธํ•œ๋‹ค. ์•„๋ž˜ ์˜ˆ์ œ์™€ ๊ฐ™์€ ํ•จ์ •์„ ์กฐ์‹ฌํ•˜์ž.

if ( it==0 ) return์ด ๋žŒ๋‹คํ•จ์ˆ˜ ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” fun dupli..Zero์˜ ๋ฐ˜ํ™˜๊ฐ’์ด ๋˜์–ด๋ฒ„๋ฆฐ๋‹ค.

 

๋งŒ์•ฝ return์„ ๊ผญ ๋žŒ๋‹คํ•จ์ˆ˜์— ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณ„๋ช…์„ ๋ถ™์—ฌ์ฃผ๋ฉด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
์‚ฌ์‹ค ์ œ์ผ ์ข‹์€๊ฑด ํ—ท๊ฐˆ๋ฆด์ผ ์—†๊ฒŒ ๋žŒ๋‹ค์— return์„ ์•ˆ์“ฐ๋Š”๊ฑฐ๊ธด ํ•˜๋‹ค.

ํ•จ์ˆ˜์˜ ์ด๋ฆ„์„ @flatMap ์ฒ˜๋Ÿผ ๋ถ™์—ฌ์ฃผ๊ฑฐ๋‚˜, ์•„๋‹˜ ์–‘์ชฝ์— ์›ํ•˜๋Š” ์ด๋ฆ„์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.
map [ [3,3] [] [5,5] ] ์ƒ์„ฑ โžก flatten โžก [3, 3, 5, 5] ๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค.

 

๊ฐ™์€ ๋งฅ๋ฝ์œผ๋กœ ๋ฐ˜๋ณต๋ฌธ ์•ˆ์—์„œ return@forEach๋ฅผ ํ•˜๋ฉด continue ์ฒ˜๋Ÿผ ๋ฃจํ”„๋ฅผ ํƒˆ์ถœํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์ดํ•ด๋ฅผ ๋•๊ธฐ์œ„ํ•จ์ด์ง€, ์ด๋ ‡๊ฒŒ ์“ฐ์ง€๋Š” ๋ง์ž.

 

์ฒ˜์Œ ๋ณด์—ฌ์ค€ ์˜ˆ์ œ์—์„œ return@๋ณ„๋ช…์„ ํ™œ์šฉํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค. [ 3, 3, 5, 5 ]

 

์ž˜ ์‚ฌ์šฉ์€ ์•ˆํ•˜์ง€๋งŒ, ์ต๋ช…ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๊ตณ์ด ๋ณ„๋ช…์„ ๋ถ™์—ฌ์ฃผ์ง€ ์•Š์•„๋„ fun-return์ด ์ •์ƒ์ ์œผ๋กœ ๋งค์นญ๋œ๋‹ค.

 

'๐ŸŒฑBackend > Kotiln' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

#2. ์ฝ”ํ‹€๋ฆฐ ๊ธฐ์ดˆ๋ฌธ๋ฒ•  (0) 2022.02.12
#1 ์ฝ”ํ‹€๋ฆฐ(Kotlin) ์ด๋ž€  (0) 2022.02.12

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ