Chapter 7 ๋น„์šฉ

์˜ค๋Š˜๋‚ ์˜ ์ฝ”๋“œ์˜ ํšจ์„์„ฑ(efficiency) ๋ฅผ ๊ด€๋Œ€ํ•˜๊ฒŒ ๋ฐ”๋ผ๋ณธ๋‹ค.

์ด๋Š” ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ €๋ ดํ•ด์ง€๊ณ  ๊ฐœ๋ฐœ์ž๋Š” ๋น„์‹ธ์กŒ๊ธฐ ๋•Œ๋ฌธ์ด๊ณ  ๋งŽ์€ ์„œ๋ฒ„๋ฅผ ์šด์˜ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•  ๋•Œ์ตœ์ ํ™”๋ฅผ ํ•˜๋ฉด ์ด๋Ÿฌํ•œ ๋น„์šฉ์„ ์ค„์ผ์ˆ˜ ์žˆ๋‹ค.

ํ”„๋กœ๊ทธ๋žจ์„ ํšจ์œจ์ ์œผ๋กœ ๋งŒ๋“ค ๋•Œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š”, ์žƒ๋Š” ๊ฒƒ์ด ๊ฑฐ์˜ ์—†๋Š” ๋ช‡๊ฐ€์ง€ ๊ณ ์ •๋œ ๊ทœ์น™์ด ์žˆ๋‹ค.

์ด๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋น„์šฉ์„ ๋“ค์ด์ง€ ์•Š๊ณ ๋„ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๊ฐ€๋…์„ฑ๊ณผ ์„ฑ๋Šฅ ์‚ฌ์ด์— ํŠธ๋ ˆ์ด๋“œ ์˜คํ”„(trade-off)๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ, ๊ฐœ๋ฐœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฌด์—‡์ด ๋” ์ค‘์š”ํ•œ์ง€ ์Šค์Šค๋กœ ๋‹ตํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

Item 45 ๋ถˆํ•„์š”ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ์„ ํ”ผํ•˜๋ผ

๊ฐ์ฒด ์ƒ์„ฑ์€ ์–ธ์ œ๋‚˜ ๋น„์šฉ์ด ๋“ค์–ด๊ฐ„๋‹ค.

๋ถˆํ•„์š”ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ์„ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ตœ์ ํ™”์˜ ๊ด€์ ์—์„œ ์ข‹๋‹ค.

JVM ์—์„œ๋Š” ํ•˜๋‚˜์˜ ๊ฐ€์ƒ ๋จธ์‹ ์—์„œ ๋™์ผํ•œ ๋ฌธ์ž์—ด์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ์žˆ๋‹ค๋ฉด, ๊ธฐ์กด์˜ ๋ฌธ์ž์—ด์„ ์žฌ์‚ฌ์šฉ ํ•œ๋‹ค.

val str1 = "Lorem ipsum dolor sit amet"
val str2 = "Lorem ipsum dolor sit amet"

println(str1 == str2)   // true
println(str1 === str2)  // true

Integer์™€ Long์ฒ˜๋Ÿผ ๋ฐ•์Šคํ™”ํ•œ ๊ธฐ๋ณธ ์ž๋ฃŒํ˜•๋„ ์ž‘์€ ๊ฒฝ์šฐ์—๋Š” ์žฌ์‚ฌ์šฉ๋œ๋‹ค. (Int๋Š” -127 ~ 127 ๋ฒ”์œ„๋ฅผ ์บ์‹œํ•ด ๋‘”๋‹ค)

val num1: Int? = 1
val num2: Int? = 1

println(num1 == num2)   // true 
println(num1 === num2)  // true

์œ„ ์ฝ”๋“œ๋Š” Integer๊ฐ€ ์žฌ์‚ฌ์šฉ ๋˜๋ฏ€๋กœ, === ๋กœ ๋น„๊ตํ–ˆ์„ ๋•Œ true ๊ฐ€ ๋œจ์ง€๋งŒ

-128 ~ 127 ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ์ˆซ์ž๋Š” ์บ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

val num3: Int? = 1234
val num4: Int? = 1234

println(num3 == num4)   // true 
println(num3 === num4)  // false

nullable ํƒ€์ž…์€ int ์ž๋ฃŒํ˜• ๋Œ€์‹  Integer ์ž๋ฃŒํ˜• ์‚ฌ์šฉ์„ ๊ฐ•์ œํ•˜๊ฒŒ ๋œ๋‹ค.

๊ธฐ๋ณธ ์ž๋ฃŒํ˜•์€ null ์ผ ์ˆ˜ ์—†๊ณ , ํƒ€์ž… ์•„๊ทœ๋จผํŠธ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ฐ์ฒด ์ƒ์„ฑ ๋น„์šฉ์€ ํ•ญ์ƒ ํด๊นŒ?

๊ฐ์ฒด๋ฅผ ๋žฉ(Wrap) ํ•˜๊ฒŒ ๋˜๋ฉด, ํฌ๊ฒŒ ์„ธ๊ฐ€์ง€ ๋น„์šฉ์ด ๋ฐœ์ƒ๋œ๋‹ค.

  • ๊ฐ์ฒด๋Š” ๋” ๋งŽ์€ ์šฉ๋Ÿ‰์„ ์ฐจ์ง€ํ•œ๋‹ค.
    • ํ—ค๋” ๋ฐ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์œ„ํ•œ ์ถ”๊ฐ€๊ณต๊ฐ„์ด ํ•„์š”ํ•˜๋‹ค.
  • ์š”์†Œ๊ฐ€ ์บก์Šํ™” ๋˜์–ด ์žˆ๋‹ค๋ฉด, ์ ‘๊ทผ์— ์ถ”๊ฐ€์ ์ธ ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ํ•„์š”ํ•˜๋‹ค.
  • ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์€ ํ•„์ˆ˜์ง€๋งŒ, ์ด๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋ฉด ๋ถˆํ•„์š”ํ•œ ๋น„์šฉ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ์ฒด ์„ ์–ธ

๋งค ์ˆœ๊ฐ„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , ๊ฐ์ฒด๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ฐ์ฒด์„ ์–ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.(์‹ฑ๊ธ€ํ†ค)

sealed class LinkedList<T>

class Node<T>(
  val head: T,
  val tail: ListedList<T>
): LinkedList<T>()

class Empty<T>: LinkedList<T>()
val list1: LinkedList<Int> = Node(1, Node(2, Empty()))
val list2: LinkedList<String> = Node("A", Node("B", Empty()))

์œ„ ๊ตฌํ˜„ ์ฝ”๋“œ์—์„œ์˜ ๋ฌธ์ œ์ ์€ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ๋งˆ๋‹ค Empty ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

Empty ์ธ์Šคํ„ด์Šค๋ฅผ ํ•˜๋‚˜๋งŒ ๋งŒ๋“ค๊ณ , ๋‹ค๋ฅธ ๋ชจ๋“  ๋ฆฌ์ŠคํŠธ์—์„œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค๋ฉด, ์ œ๋„ค๋ฆญ ํƒ€์ž…์ด ์ผ์น˜ ํ•˜์ง€ ์•Š์•„ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๋ชจ๋“  ํƒ€์ž…์˜ ์„œ๋ธŒํƒ€์ž…์ธ Nothing ์„ ์ด์šฉํ•˜๋Š”๊ฒƒ์ด๋‹ค.

sealed class LinkedList<T>

class Node<T>(
  val head: T,
  val tail: ListedList<T>
): LinkedList<T>()

class Empty<T>: LinkedList<Noting>()
val list1: LinkedList<Int> = Node(1, Node(2, Empty))
val list2: LinkedList<String> = Node("A", Node("B", Empty))

์บ์‹œ๋ฅผ ํ™œ์šฉํ•˜๋Š” ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜

ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋Š” ์บ์‹œ(cache)๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ž˜์„œ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋Š” ํ•ญ์ƒ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค.

์‹ค์ œ๋กœ stdlib ์˜ emptyList ๋Š” ์ด๋ฅผ ํ™œ์šฉํ•ด์„œ ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค.

fun <T> List<T> emptyList() {
  return EMPTY_LIST
}

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

์ฐธ๊ณ ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋„ ๋น„์Šทํ•œ ํ˜•ํƒœ๋กœ ์ปค๋„ฅ์…˜ํ’€์„ ์‚ฌ์šฉํ•œ๋‹ค.

๊ฐ์ฒด ์ƒ์„ฑ์ด ๋ฌด๊ฒ๊ฑฐ๋‚˜ ์—ฌ๋Ÿฌ mutable ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ด์ฒ˜๋Ÿผ ๊ฐ์ฒด ํ’€์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

๋ชจ๋“  ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋Š” ๋ฉ”๋ชจ์ด์ œ์ด์…˜(memoization) ์„ ํ™œ์šฉํ•˜์—ฌ ์บ์‹ฑ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฉ”๋ชจ์ด์ œ์ด์…˜ (Memoization)
์ด์ „์— ์—ฐ์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ํŒจํ„ด
๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ์ž„์‹œ ์ €์žฅ๊ฐ’์„ ์ €์žฅํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๋งŽ์ด ์ค„์ธ๋‹ค

๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•  ๋•Œ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ(Garbage Collector, GC)๊ฐ€ ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•ด ์ฃผ๋Š” SoftReference๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋” ์ข‹๋‹ค.

  • WeakReference: ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ๊ฐ’์„ ์ •๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์ง€ ์•Š๋Š”๋‹ค. ๋‹ค๋ฅธ ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ์ด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ๊ณง๋ฐ”๋กœ ์ œ๊ฑฐ๋œ๋‹ค.
  • SoftReference: ๊ฐ€๋น„์ž ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ๊ฐ’์„ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๊ณ , ์ •๋ฆฌํ•˜์ง€ ์•Š์„์ˆ˜๋„ ์žˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ€์กฑํ•ด์„œ ์ถ”๊ฐ€๋กœ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ •๋ฆฌํ•œ๋‹ค.

์บ์‹œ๋Š” ์–ธ์ œ๋‚˜ ๋ฉ”๋ชจ๋ฆฌ์™€ ์„ฑ๋Šฅ์˜ ํŠธ๋ ˆ์ด๋“œ ์˜คํ”„๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ, ์บ์‹œ๋ฅผ ์ž˜ ์„ค๊ณ„ํ•˜๋Š”๊ฒƒ์€ ์‰ฝ์ง€ ์•Š๋‹ค.

์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ƒํ™ฉ์„ ์ž˜ ๊ณ ๋ คํ•˜์—ฌ ํ˜„๋ช…ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜์ž.

๋ฌด๊ฑฐ์šด ๊ฐ์ฒด๋ฅผ ์™ธ๋ถ€ ์Šค์ฝ”ํ”„๋กœ ๋ณด๋‚ด๊ธฐ

์„ฑ๋Šฅ์„ ์œ„ํ•œ ์œ ์šฉํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๋ฌด๊ฑฐ์šด ๊ฐ์ฒด๋ฅผ ์™ธ๋ถ€ ์Šค์ฝ”ํ”„๋กœ ๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

Iterable ๋‚ด๋ถ€์˜ ํ™•์žฅ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์ตœ๋Œ“๊ฐ’์„ ๋‚˜ํƒ€๋‚ด๋Š” max ๋ฅผ countMax ํ•จ์ˆ˜์˜ ๋ ˆ๋ฒจ๋กœ ์˜ฎ๊ฒผ๋‹ค.

fun <T: Comparable<T>> Iterable<T>.countMax(): Int {
  val max = this.max()
  return count = { it == max }
}

ํ™•์žฅ ๋ฆฌ์‹œ๋ฒ„๋กœ max ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ˜•ํƒœ๊ฐ€ ํ™•์‹คํ•˜๊ฒŒ ๋ณด์ด๋ฏ€๋กœ ๊ฐ€๋…์„ฑ์ด ํ–ฅ์ƒ๋œ๋‹ค.

๋ฐ˜๋ณต ์ฒ˜๋ฆฌ์ค‘์— max ๊ฐ’์„ ํ•œ๋ฒˆ๋งŒ ํ™•์ธํ•˜๋ฏ€๋กœ ์ฝ”๋“œ์˜ ์„ฑ๋Šฅ์ด ์ข‹์•„์ง„๋‹ค.

์ง€์—ฐ ์ดˆ๊ธฐํ™”

๋ฌด๊ฑฐ์šด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ์ง€์—ฐ๋˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

ํ•˜์ง€๋งŒ ๋ฌด๊ฑฐ์šด ๊ฐ์ฒด๋ฅผ ๊ฐ€์กŒ์ง€๋งŒ ์‘๋‹ต์€ ๋นจ๋ผ์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ข‹์ง€ ์•Š๋Š” ์ผ€์ด์Šค๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค.

์ง€์—ฐ ์ดˆ๊ธฐํ™”๋Š” ์ƒํ™ฉ์— ๋งž๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๊ธฐ๋ณธ ์ž๋ฃŒํ˜• ์‚ฌ์šฉํ•˜๊ธฐ

์ฝ”ํ‹€๋ฆฐ/JVM ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ๊ธฐ๋ณธ ์ž๋ฃŒํ˜•์„ ์‚ฌ์šฉํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ€์ด์Šค์—์„œ๋Š” ๊ธฐ๋ณธ ์ž๋ฃŒํ˜•์„ ๋žฉ(Wrap) ํ•œ ์ž๋ฃŒํ˜•์„ ์‚ฌ์šฉํ•œ๋‹ค.

  • nullable ํƒ€์ž…์„ ์—ฐ์‚ฐํ•  ๋•Œ (๊ธฐ๋ณธ ์ž๋ฃŒํ˜•์€ null ์ผ ์ˆ˜ ์—†๋‹ค.)
  • ํƒ€์ž…์„ ์ œ๋„ค๋ฆญ์œผ๋กœ ์‚ฌ์šฉํ•  ๋•Œ
์ฝ”ํ‹€๋ฆฐ์˜ ์ž๋ฃŒํ˜• ์ž๋ฐ”์˜ ์ž๋ฃŒํ˜•
Int int
Int? Integer
List<Int> List<Integer>

์ˆซ์ž์™€ ๊ด€๋ จ๋œ ์—ฐ์‚ฐ์€ ์–ด๋–ค ํ˜•ํƒœ์˜ ์ž๋ฃŒํ˜•์„ ์‚ฌ์šฉํ•˜๋‚˜ ์„ฑ๋Šฅ์ ์œผ๋กœ ํฐ ์ฐจ์ด๋Š” ์—†๋‹ค.

๊ต‰์žฅํžˆ ํฐ ์ปฌ๋ ‰์…˜์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์ฐจ์ด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ธฐ์กด ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ๋˜๋˜ ์ž๋ฃŒํ˜•์„ ์ผ๊ด„ ๋ณ€๊ฒฝํ•˜๋ฉด, ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

์ •๋ฆฌ

๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์•˜๋‹ค.

๋ช‡๊ฐ€์ง€๋Š” ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ํ–ฅ์ƒ์‹œ์ผœ ์ฃผ๋Š” ์žฅ์ ๋„ ์žˆ์œผ๋ฏ€๋กœ ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

Item 46 ํ•จ์ˆ˜ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ–๋Š” ํ•จ์ˆ˜์— inline ํ•œ์ •์ž๋ฅผ ๋ถ™์—ฌ๋ผ

์ฝ”ํ‹€๋ฆฐ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ณ ์ฐจ ํ•จ์ˆ˜(higher-order function)๋ฅผ ์‚ดํŽด๋ณด๋ฉด, ๋Œ€๋ถ€๋ถ„ inline ํ•œ์ •์ž๊ฐ€ ๋ถ™์–ด ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

inline fun repeat(times: Int, action: (Int) -> Unit) {
  for (index in 0 until times) {
    action(index)
  }
}
repeat(10) {
  println(it)
}

์ปดํŒŒ์ผ ์‹œ์ ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋Œ€์ฒด๋œ๋‹ค.

for (index in 0 until times) {
  println(index)
}

์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ•จ์ˆ˜ ๋ณธ๋ฌธ์œผ๋กœ ์ ํ”„ํ•˜๊ณ , ๋ณธ๋ฌธ์˜ ๋ชจ๋“  ๋ฌธ์žฅ์„ ํ˜ธ์ถœํ•œ ํ›„, ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ๋˜ ์œ„์น˜๋กœ ๋‹ค์‹œ ์ ํ”„ํ•˜๋Š” ๊ณผ์ •์„ ๊ฑฐ์นœ๋‹ค.

inline ํ•œ์ •์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์ด ์žˆ๋‹ค.

  1. ํƒ€์ž… ์•„๊ทœ๋จผํŠธ์— reified ํ•œ์ •์ž๋ฅผ ๋ถ™์—ฌ์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ํ•จ์ˆ˜ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ง„ ํ•จ์ˆ˜๊ฐ€ ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.
  3. ๋น„์ง€์—ญ(non-local) ๋ฆฌํ„ด์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

ํƒ€์ž… ์•„๊ทœ๋จผํŠธ๋ฅผ reified๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

reified ํ•œ์ •์ž๋ฅผ ์ง€์ •ํ•˜๋ฉด, ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•œ ๋ถ€๋ถ„์ด ํƒ€์ž… ์•„๊ทœ๋จผํŠธ๋กœ ๋Œ€์ฒด๋œ๋‹ค.

inline fun <reified T> printTypeName() {
  print(T::class.simpleName)
}
printTypeName<Int>()      // Int
printTypeName<Char>()     // Char
printTypeName<String>()   // String

์ปดํŒŒ์ผ ํ•˜๋Š” ๋™์•ˆ printTypeName ์˜ ๋ณธ๋ฌธ์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋Œ€์ฒด๋œ๋‹ค.

print(Int::class.simpleName)    // Int 
print(Char::class.simpleName)   // Char
print(String::class.simpleName) // String

ํ•จ์ˆ˜ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ง„ ํ•จ์ˆ˜๊ฐ€ ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

๋ชจ๋“  ํ•จ์ˆ˜๋Š” inline ํ•œ์ •์ž๋ฅผ ๋ถ™์ด๋ฉด ์กฐ๊ธˆ๋” ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

ํ•จ์ˆ˜ ํ˜ธ์ถœ๊ณผ ๋ฆฌํ„ด์„ ์œ„ํ•ด ์ ํ”„ํ•˜๋Š” ๊ณผ์ •๊ณผ ๋ฐฑ์Šคํƒ์„ ์ถ”์ ํ•˜๋Š” ๊ณผ์ •์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทธ๋ž˜์„œ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์žˆ๋Š” ๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜๋“ค์—๋Š” ๋Œ€๋ถ€๋ถ„ inline ํ•œ์ •์ž๊ฐ€ ๋ถ™์–ด ์žˆ๋‹ค.

inline fun print(message: Any?) {
  System.out.print(message)
}

์ฝ”ํ‹€๋ฆฐ/JVM ์—์„œ๋Š” JVM ์ต๋ช… ํด๋ž˜์Šค ๋˜๋Š” ์ผ๋ฐ˜ ํด๋ž˜์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ, ํ•จ์ˆ˜๋ฅผ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด ๋‚ธ๋‹ค.

val lambda: () -> Unit = {
  // Codes
}

์œ„์™€ ๊ฐ™์€ ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ํด๋ž˜์Šค๋กœ ์ปดํŒŒ์ผ ๋œ๋‹ค.

Function0(Unit) lambda = new Function0<Unit>() {
  public Unit invoke() {
    // Codes
  }
}

๋ณ„๋„์˜ ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ๋Š” ์ผ๋ฐ˜ ํด๋ž˜์Šค๋กœ ์ปดํŒŒ์ผํ•˜๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

public class Test$lambda implements Function0<Unit> {
  public Unit invoke() {
    // Codes
  }
}
Function0 lambda = new Test$lambda()

๋‘ ๋ฐฉ์‹์˜ ํฐ ์ฐจ์ด๋Š” ์—†์œผ๋ฉฐ JVM ์—์„œ ์•„๊ทœ๋จผํŠธ๊ฐ€ ์—†๋Š” ํ•จ์ˆ˜ํƒ€์ž…์€ Function0 ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜๋œ๋‹ค.

  • () -> Unit ์€ Function0<Unit> ๋กœ ์ปดํŒŒ์ผ
  • () -> Int ์€ Function0<Int> ๋กœ ์ปดํŒŒ์ผ
  • (Int) -> Int ์€ Function0<Int, Int> ๋กœ ์ปดํŒŒ์ผ
  • (Int, Int) -> Int ์€ Function0<Int, Int, Int> ๋กœ ์ปดํŒŒ์ผ

์ด๋Ÿฌํ•œ ๋ชจ๋“  ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ชจ๋‘ ์ฝ”ํ‹€๋ฆฐ ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์ƒ์„ฑ๋œ๋‹ค.

์š”์ฒญ์ด ์žˆ์„๋•Œ ์ƒ์„ฑ๋˜๋ฏ€๋กœ, ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ๋Œ€์‹  ํ•จ์ˆ˜ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋น„์ง€์—ญ์  ๋ฆฌํ„ด(non-local return) ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

fun repeatNoinline(times: Int, action: (Int) -> Unit) {
  for (index in 0 until times) {
    action(index)
  }
}

repeatNoinline ์€ ๋‚ด๋ถ€์—์„œ ๋ฆฌํ„ด์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

fun main() {
  repeatNninline(10) {
    print(it)
    return    // ์˜ค๋ฅ˜: ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค. 
  }
}

์ด๋Š” ํ•จ์ˆ˜ ๋ฆฌํ„ฐ๋Ÿด์ด ์ปดํŒŒ์ผ๋  ๋•Œ, ํ•จ์ˆ˜๊ฐ€ ๊ฐ์ฒด๋กœ ๋ž˜ํ•‘๋˜์–ด ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ด๋‹ค.

์ธ๋ผ์ธ์ด๋ผ๋ฉด ์ด๋Ÿฌํ•œ ์ œํ•œ์ด ์—†๋‹ค. ํ•จ์ˆ˜๊ฐ€ main ํ•จ์ˆ˜ ๋‚ด๋ถ€์— ๋ฐ•ํžˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

fun main() {
  repeat(10) {
    print(it)
    return    // OK
  }
}

๋•๋ถ„์— ์ œ์–ด๋ฌธ์ฒ˜๋Ÿผ ๋ณด์ด๋ฉด์„œ๋„ ์ž˜ ๋™์ž‘ํ•œ๋‹ค.

fun getSomeMoney(): Money? {
  repeat(100) {
    val money = searchForMoney()
    if (money != null) return money
  }
  return null
}

inline ํ•œ์ •์ž์˜ ๋น„์šฉ

inline ํ•œ์ •์ž๋Š” ์œ ์šฉํ•˜์ง€๋งŒ ๋ชจ๋“ ๊ณณ์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

๋Œ€ํ‘œ์ ์œผ๋กœ๋Š” ์žฌ๊ท€์ ์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์—†๋‹ค. ๋งŒ์•ฝ ์žฌ๊ท€๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋ฌดํ•œํžˆ ๋Œ€์ฒด๋˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜๋ฉฐ, ์ด๋Ÿฌํ•œ ์˜ค๋ฅ˜๋ฅผ IDE ์—์„œ ์žก์•„์ค„ ์ˆ˜ ์—†์–ด ๊ต‰์žฅํžˆ ์œ„ํ—˜ํ•˜๋‹ค.

inline ํ•œ์ •์ž๋ฅผ ๋‚จ์šฉํ•˜๋ฉด, ์ฝ”๋“œ์˜ ํฌ๋ฆฌ๊ฐ€ ์‰ฝ๊ฒŒ ์ปค์ง„๋‹ค.

์„œ๋กœ ํ˜ธ์ถœํ•˜๋Š” ์ธ๋ผ์ธ ํ•จ์ˆ˜๊ฐ€ ๋งŽ์•„์ง€๋ฉด ์ฝ”๋“œ๊ฐ€ ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋ฏ€๋กœ ์œ„ํ—˜ํ•˜๋‹ค.

crossinline ๊ณผ oninline

ํ•จ์ˆ˜๋ฅผ ์ธ๋ผ์ธ์œผ๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ์ง€๋งŒ, ์–ด๋–ค ์ด์œ ๋กœ ์ผ๋ถ€ ํ•จ์ˆ˜ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” inline์œผ๋กœ ๋ฐ›๊ณ  ์‹ถ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์„ ์ˆ˜๋„ ์žˆ๋‹ค.

  • crossinline: ์•„๊ทœ๋จผํŠธ๋กœ ์ธ๋ผ์ธ ํ•จ์ˆ˜๋ฅผ ๋ฐ›์ง€๋งŒ, ๋น„์ง€์—ญ์  ๋ฆฌํ„ด์„ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ›์„์ˆ˜ ์—†๊ฒŒ ๋งŒ๋“ ๋‹ค. ์ธ๋ผ์ธ์œผ๋กœ ๋งŒ๋“ค์ง€ ์•Š์€ ๋‹ค๋ฅธ ๋žŒ๋‹ค ํ‘œํ˜„์‹๊ณผ ์กฐํ•ฉํ•ด์„œ ์‚ฌ์šฉํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • noinline: ์•„๊ทœ๋จผํŠธ๋กœ ์ธ๋ผ์ธ ํ•จ์ˆ˜๋ฅผ ๋ฐ›์„ ์ˆ˜ ์—†๊ฒŒ ๋งŒ๋“ ๋‹ค. ์ธ๋ผ์ธ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ ํ•จ์ˆ˜๋ฅผ ์•„๊ทœ๋จผํŠธ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ ํ™œ์šฉํ•œ๋‹ค.

๋‹คํ–‰์Šค๋Ÿฝ๊ฒŒ๋„ ๋‘ ํ•œ์ •์ž์— ๋Œ€ํ•ด์„œ๋Š” IDE ์—์„œ ์ œ์•ˆํ•ด์ค€๋‹ค. (๋Œ€์ถฉ ์•Œ๊ธฐ๋งŒ ํ•ด๋„ ๋œ๋‹คํ•จ)

์ •๋ฆฌ

์ธ๋ผ์ธ ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ์ฃผ์š” ์‚ฌ๋ก€๋ฅผ ์ •๋ฆฌํ•ด ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • print ํ•จ์ˆ˜์ฒ˜๋Ÿผ ๋งค์šฐ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ
  • filterIsInstance ํ•จ์ˆ˜์ฒ˜๋Ÿผ ํƒ€์ž… ์•„๊ทœ๋จผํŠธ๋กœ reified ํƒ€์ž…์„ ์ „๋‹ฌ๋ฐ›๋Š” ๊ฒฝ์šฐ
  • ํ•จ์ˆ˜ ํƒ€์ž…์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ–๋Š” ํ†ฑ๋ ˆ๋ฒจ ํ•ฉ์ˆ˜๋ฅผ ์ •์˜ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ

API ๋ฅผ ์ •์˜ํ•  ๋•Œ ์ธ๋ผ์ธ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ฑฐ์˜ ์—†๋‹ค.

ํ•œ ์ธ๋ผ์ธ ํ•จ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ์ธ๋ผ์ธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ, ์ฝ”๋“œ๊ฐ€ ๊ธฐํ•˜๊ธ‰์ˆ˜์ ์œผ๋กœ ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ์˜ํ•˜๋ผ

Item 47 ์ธ๋ผ์ธ ํด๋ž˜์Šค์˜ ์‚ฌ์šฉ์„ ๊ณ ๋ คํ•˜๋ผ

์ธ๋ผ์ธ์€ ํ•จ์ˆ˜ ๋ฟ๋งŒ์ด ์•„๋‹ˆ๋ผ, ํ•˜๋‚˜์˜ ๊ฐ’์„ ๋ณด์œ ํ•˜๋Š” ๊ฐ์ฒด๋„ ์ธ๋ผ์ธ์œผ๋กœ ๋งŒ๋“ค์ˆ˜ ์žˆ๋‹ค.

์ฝ”ํ‹€๋ฆฐ 1.3 ๋ถ€ํ„ฐ ๋„์ž…๋œ ์ด ๊ธฐ๋Šฅ์€ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž ํ”„๋กœํผํ‹ฐ๊ฐ€ ํ•˜๋‚˜์ธ ํด๋ž˜์Šค ์•ž์— inline ์„ ๋ถ™์ด๋ฉด, ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์œ„์น˜๊ฐ€ ๋ชจ๋‘ ํ”„๋กœํผํ‹ฐ๋กœ ๊ต์ฒด๋œ๋‹ค.

inline class Name(private val value: String)

์ด๋Ÿฌํ•œ inline ํด๋ž˜์Šค๋Š” ํƒ€์ž…๋งŒ ๋งž๋‹ค๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ทธ๋ƒฅ ๊ฐ’์„ ๊ณง๋ฐ”๋กœ ์ง‘์–ด๋„ฃ๋Š” ๊ฒƒ๋„ ํ—ˆ์šฉ๋œ๋‹ค.

val name: Name = Name("Marcin")

// ์ปดํŒŒ์ผ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ๋ฐ”๋€๋‹ค.
val name: String = "Marcin"

์ธ๋ผ์ธ ํด๋ž˜์Šค๋Š” ๋‹ค๋ฅธ ์ž๋ฃŒํ˜•์„ ๋ž˜ํ•‘ํ•ด์„œ ์ƒˆ๋กœ์šด ์ž๋ฃŒํ˜•์œผ๋กœ ๋งŒ๋“ค ๋•Œ ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ค. ์ด๋•Œ ์–ด๋– ํ•œ ์˜ค๋ฒ„๋ ˆ๋“œ๋„ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค (Item 45)

์ธ๋ผ์ธ ํด๋ž˜์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ๋งŽ์ด ๋ฐœ์ƒํ•œ๋‹ค.

  • ์ธก์ • ๋‹จ์œ„๋ฅผ ํ‘œํ˜„ํ•  ๋•Œ
  • ํƒ€์ž… ์˜ค์šฉ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ๋ง‰์„ ๋•Œ

์ธก์ • ๋‹จ์œ„๋ฅผ ํ‘œํ˜„ํ•  ๋•Œ

interface Timer {
  fun callAfter(time: Int, callback: () -> Unit)
}

์œ„ callAfter ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ time ๋‹จ์œ„๊ฐ€ ๋ถˆ๋ช…ํ™•ํ•˜์—ฌ ์˜คํ•ด๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„์— ์ธก์ • ๋‹จ์œ„๋ฅผ ๋ถ™์—ฌ์ฃผ๋Š”๊ฒƒ์ด ๋ฌธ์ œํ•ด๊ฒฐ์„ ์œ„ํ•œ ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์ด๋‹ค.

interface Timer {
  fun callAfter(timeMillis: Int, callback: () -> Unit)
}

๋” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ํƒ€์ž…์— ์ œํ•œ์„ ๊ฑฐ๋Š” ๊ฒƒ์ด๋‹ค.

inline class Minutes(val minutes: Int) {
  fun toMillis(): Millis = Millis(minutes * 60 * 1000)
  // ...
}

inline class Millis(val milliseconds: Int) {
  // ...
}

interface User {
  fun decideAboutTime(): Minutes
  fun wakeUp()
}

interface Timer {
  fun callAfter(timeMillis: Millis, callback: () -> Unit)
}

fun setUpUserWakeUpUser(user: User, timer: Timer) {
  val time: Int = user.decideAboutTime()
  timer.callAfter(time) {   // ์˜ค๋ฅ˜: Type mismatch
    user.wakeUp()
  }
}

์•„๋ž˜์™€ ๊ฐ™์ด ์˜ฌ๋ฐ”๋ฅธ ํƒ€์ž…์„ ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ๋‹ค.

fun setUpUserWakeUpUser(user: User, timer: Timer) {
  val time: Int = user.decideAboutTime()
    timer.callAfter(time.toMillis()) {
      user.wakeUp()
    }
}

๊ฐ์ฒด์ƒ์„ฑ์„ ์œ„ํ•ด ๋ฏธ๋ฆฌ ํ™•์žฅ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค์–ด ๋‘์–ด๋„ ์ข‹๋‹ค.

inline val Int.min
  get() = Minutes(this)
    
inline val Int.ms
  get() = Millis(this)
    
val timeMin: Minutes = 10.min

ํƒ€์ž… ์˜ค์šฉ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ๋ง‰์„ ๋•Œ

@Entity(tableName="grades")
classGrades(
  @ColumnInfo(name = "studentId")
  val studentId: Int,

  @ColumnInfo(name = "teacherId")
  val teacherId: Int,

  @ColumnInfo(name = "schoolId")
  val schoolId: Int,

  // ...
)

๋ชจ๋“  ID ๊ฐ€ Int ์ž๋ฃŒํ˜•์ด๊ธฐ ๋•Œ๋ฌธ์—, ์‹ค์ˆ˜๋กœ ์ž˜๋ชป๋œ ๊ฐ’์„ ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด Int ์ž๋ฃŒํ˜• ๊ฐ’์„ inline ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ž˜ํ•‘ํ•˜์ž

inline class StudentId(val studentId: Int)
inline class TeachetId(val teacherId: Int)
inline class SchoolId(val schoolId: Int)

@Entity(tableName="grades")
classGrades(
  @ColumnInfo(name = "studentId")
  val studentId: Int,

  @ColumnInfo(name = "teacherId")
  val teacherId: Int,

  @ColumnInfo(name = "schoolId")
  val schoolId: Int,

  // ...
)

์ธ๋ผ์ธ ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค

์ธ๋ผ์ธ ํด๋ž˜์Šค์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ํƒ€์ž…์„ ๋‚˜ํƒ€๋‚ด๋ ค๋ฉด, ๊ฐ์ฒด๋ฅผ ๋ž˜ํ•‘ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ธ๋ผ์ธ ํด๋ž˜์Šค๋Š” ์•„๋ฌด๋Ÿฐ ์˜๋ฏธ๊ฐ€ ์—†๋‹ค.

typealias

typealias ์‚ฌ์šฉํ•˜๋ฉด, ํƒ€์ž…์— ์ƒˆ๋กœ์šด ์ด๋ฆ„์„ ๋ถ™์—ฌ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

์ •๋ฆฌ

์ธ๋ผ์ธ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์ ์ธ ์˜ค๋ฒ„ํ—ค๋“œ ์—†์ด ํƒ€์ž…์„ ๋ž˜ํ•‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ธ๋ผ์ธ ํด๋ž˜์Šค๋Š” ํƒ€์ž… ์‹œ์Šคํ…œ์„ ํ†ตํ•ด ์‹ค์ˆ˜๋กœ ์ฝ”๋“œ๋ฅผ ์ž˜๋ชป ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์•„์ฃผ๋ฏ€๋กœ, ์ฝ”๋“œ์˜ ์•ˆ์ •์„ฑ์„ ํ–ฅ์ƒ์‹œ์ผœ์ค€๋‹ค.

Item 48 ๋”์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฐ์ฒด์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ œ๊ฑฐํ•˜๋ผ

๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด์ฃผ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ์ต์ˆ™ํ•œ ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ์ฒด ํ•ด์ œ(free)๋ฅผ ๋”ฐ๋กœ ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š”๋‹ค.

๊ทธ๋ ‡๋‹ค๊ณ  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌ๋ฅผ ์™„์ „ํžˆ ๋ฌด์‹œํ•ด๋ฒ„๋ฆฌ๋ฉด, ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜(๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋น„)๊ฐ€ ๋ฐœ์ƒํ•ด์„œ, ์ƒํ™ฉ์— ๋”ฐ๋ผ OOM(Out Of Memory Error)์ด ๋ฐœ์ƒํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฐ์ฒด์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์œ ์ง€ํ•˜๋ฉด ์•ˆ๋œ๋‹ค์˜ ๊ทœ์น™์€ ์ง€์ผœ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

ํŠนํžˆ ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋งŽ์ด ์ฐจ์ง€ํ•˜๊ฑฐ๋‚˜, ์ธ์Šคํ„ด์Šค๊ฐ€ ๋งŽ์ด ์ƒ์„ฑ๋  ๊ฒฝ์šฐ์—๋Š” ๋ฐ˜๋“œ์‹œ ์ง€์ผœ์ค˜์•ผ ํ•œ๋‹ค.

์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ๋•Œ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์—ผ๋‘ํ•ด ๋‘์–ด์•ผ ํ•œ๋‹ค. ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ๋Š” ๋ฉ”๋ชจ๋ฆฌ์™€ ์„ฑ๋Šฅ ๋ฟ๋งŒ์ด ์•„๋‹ˆ๋ผ ๊ฐ€๋…์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ํ•ญ์ƒ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค.