λ‘œμΌ“πŸΎ
article thumbnail
λ°˜μ‘ν˜•

이 κΈ€μ˜ λ‚΄μš©μ€ [μ΄νŽ™ν‹°λΈŒ μ½”ν‹€λ¦°]을 μ°Έκ³ ν•©λ‹ˆλ‹€.

 

λ•Œλ‘œλŠ” 데이터λ₯Ό ν•œκΊΌλ²ˆμ— 전달해야 ν•  λ•Œκ°€ μžˆμŠ΅λ‹ˆλ‹€. μ•„λž˜ μ½”λ“œμ²˜λŸΌ 말이죠.

 

data class Player(
	val id: Int,
    val name: String,
    val points: Int
)

val player = Player(0, "Gecko", 9999)

 

data ν•œμ •μžλŠ” μ•„λž˜μ˜ ν•¨μˆ˜λ“€μ„ μžλ™μœΌλ‘œ μƒμ„±ν•΄μ€λ‹ˆλ‹€.

  • toString
  • equals 와 hashCode
  • copy
  • componentN(component1, component2 λ“±)

toString

클래슀의 이름과 κΈ°λ³Έ μƒμ„±μž ν˜•νƒœλ‘œ λͺ¨λ“  ν”„λ‘œνΌν‹°μ™€ 값을 좜λ ₯ ν•΄μ€λ‹ˆλ‹€. 주둜 둜그 좜λ ₯μ΄λ‚˜ 디버깅 ν• λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.

println(player) // Player(id=0, name=Gecko, points=9999)

 

equals

κΈ°λ³Έ μƒμ„±μžμ˜ ν”„λ‘œνΌν‹°κ°€ 같은지 ν™•μΈν•΄μ€λ‹ˆλ‹€. hashCode 와 equals λŠ” 같은 κ²°κ³Όλ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

player == Player(0, "Gecko", 9999) // true
player == Player(0, "Ross", 9999) // false

 

Copy

immutable 데이터 클래슀λ₯Ό λ§Œλ“€ λ•Œ νŽΈλ¦¬ν•©λ‹ˆλ‹€. copyλŠ” κΈ°λ³Έ μƒμ„±μž ν”„λ‘œνΌν‹°κ°€ 같은 μƒˆλ‘œμš΄ 객체λ₯Ό λ³΅μ œν•©λ‹ˆλ‹€.

val newObj = player.copy(name = "Thor")
print(newObj) // Player(id=0, name=Thor, points=99999)

copy λ©”μ„œλ“œλŠ” 얕은 λ³΅μ‚¬μ΄μ§€λ§Œ immutable 객체라면 상관이 μ—†μŠ΅λ‹ˆλ‹€. μ–΄μ°¨ν”Ό ν”„λ‘œνΌν‹° 변경이 λΆˆκ°€λŠ₯ν• ν…Œλ‹ˆκΉŒμš”.

 

ComponentN ν•¨μˆ˜(Component1, Component2 λ“±)

μœ„μΉ˜λ₯Ό 기반으둜 객체λ₯Ό ν•΄μ œν•  수 있게 ν•΄μ€λ‹ˆλ‹€.

val (id, name, pts) = player

μ΄λ ‡κ²Œ 객체λ₯Ό ν•΄μ œν•˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•˜λ©΄, 코틀린은 λ‚΄λΆ€μ μœΌλ‘œ componentN ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” μ•„λž˜μ™€ 같은 μ½”λ“œλ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.

// 컴파일 ν›„
val id: Int = player.component1()
val name: String = player.component2()
val pts: Int = player.component3()

μ΄λ ‡κ²Œ 객체λ₯Ό ν•΄μ œν•˜λ©΄ μž₯점과 단점이 μžˆμŠ΅λ‹ˆλ‹€.

 

μž₯점

  • λ³€μˆ˜μ˜ 이름을 μ›ν•˜λŠ” λŒ€λ‘œ 지정할 수 μžˆμŠ΅λ‹ˆλ‹€.
val visited = listOf("Korea", "Russia", "USA")
val (first, second, third) = visited
println("$first $second $third") // Korea Russia USA

val trip = mapOf(
	"Korea" to "Seoul",
	"Russia" to "moscow",
	"USA" to "Wasinton"
)

for ((country, city) in trip) {
	println("We Loved $city in $country")
}

 

단점

  • μœ„μΉ˜λ₯Ό 잘λͺ» μ§€μ •ν•˜λ©΄ λ‹€μ–‘ν•œ λ¬Έμ œκ°€ λ°œμƒ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 


νŠœν”Œ λŒ€μ‹  데이터 클래슀 μ‚¬μš©ν•˜κΈ°

데이터 ν΄λž˜μŠ€λŠ” νŠœν”Œλ³΄λ‹€ λ§Žμ€ 것을 μ œκ³΅ν•©λ‹ˆλ‹€.

 

νŠœν”Œμ˜ 단점

  • νŠœν”Œμ€ 데이터 ν΄λž˜μŠ€μ™€ 같은 역할을 ν•˜μ§€λ§Œ 훨씬 가독성이 λ–¨μ–΄μ§‘λ‹ˆλ‹€.
  • νŠœν”Œλ§Œ 보고 μ–΄λ–€ νƒ€μž…μ„ λ‚˜νƒ€λ‚΄λŠ”μ§€ 예츑이 μ–΄λ ΅μŠ΅λ‹ˆλ‹€.

 

κ²°κ΅­ νŠœν”Œλ³΄λ‹€ 데이터 클래슀λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 λͺ¨λ“  λ©΄μ—μ„œ μ’‹κΈ° λ•Œλ¬Έμ— νŠœν”Œμ€ 점차 없어지고 μžˆμŠ΅λ‹ˆλ‹€.

κ°„λ‹¨ν•œ μ˜ˆμž…λ‹ˆλ‹€.

 

fun String.parseName(): Pair<String, String>? {
		val indexOfLastSpace = this.trim().lastIndexOf(' ')
		if(indexOfLastSpace < 0) return null
		val firstName = this.take(indexOfLastSpace)
		val lastName = this.drop(indexOfLastSpace)
		return Pair(firstName, lastName)
}

// μ‚¬μš©
val fullName = "Marcin Moskata"
val (fisrtName, lastName) = fullName.parseName() ?: return

 

μœ„ μ½”λ“œμ˜ 문제점

  • Pair<String, String> 을 보고 전체 이름을 λ‚˜νƒ€λ‚Έλ‹€λŠ” 것을 μΈμ§€ν•˜κΈ°κ°€ μ–΄λ ΅μŠ΅λ‹ˆλ‹€.
  • lastNameκ³Ό firstName 쀑 μ–΄λ–€ 것이 μ•žμ— μžˆμ„μ§€ μ˜ˆμΈ‘ν•˜κΈ°κ°€ μ–΄λ ΅μŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ νŠœν”Œλ³΄λ‹¨ 데이터 클래슀λ₯Ό ν™œμš©ν•˜μž!!

 

data class FullName(
		val firstName: String,
		val lastName: String
)

fun String.parseName(): FullName? {
		val indexOfLastSpace = this.trim().lastIndexOf(' ')
		if(indexOfLastSpace < 0) return null
		val firstName = this.take(indexOfLastSpace)
		val lastName = this.drop(indexOfLastSpace)
		return FullName(firstName, lastName)
}

// μ‚¬μš©
val fullName = "Marcin Moskata"
val (fisrtName, lastName) = fullName.parseName() ?: return

 

데이터 클래슀λ₯Ό μ‚¬μš©ν–ˆμ„ λ•Œμ˜ μž₯점

  • ν•¨μˆ˜μ˜ 리턴 νƒ€μž…μ΄ λͺ…ν™•ν•΄μ§‘λ‹ˆλ‹€. → Pair<String, String> λŒ€μ‹  FullName μ‚¬μš©
  • μ‚¬μš©μžκ°€ 데이터 ν΄λž˜μŠ€μ— μ ν˜€ μžˆλŠ” 것과 λ‹€λ₯Έ 이름을 ν™œμš©ν•΄ λ³€μˆ˜λ₯Ό ν•΄μ œν•˜λ©΄, κ²½κ³ κ°€ 좜λ ₯λ©λ‹ˆλ‹€.

 

이처럼 데이터 클래슀λ₯Ό ν™œμš©ν•˜λ©΄ νŠœν”Œμ„ ν™œμš©ν•  λ•Œλ³΄λ‹€ 더 λ§Žμ€ μž₯점이 μžˆμŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ 클래슀λ₯Ό ν™œμš©ν•˜λŠ”λ° 두렀움을 κ°–κΈ° 말고, 적극적으둜 ν™œμš©ν•©μ‹œλ‹€.

λ°˜μ‘ν˜•
profile on loading

Loading...