Part2 ์ฒซ ์ฅ์ด๋ค. ์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ, ๋ฉ์๋ ๋ค์ด๋ฐ ์ปจ๋ฒค์ , ์์ ํ๋กํผํฐ์ ๋ํ ๋ด์ฉ์ด ๋์จ๋ค.
operator
์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ์ด๋ค.
data class Point(val x: Int, val y: Int)
operator fun Point.plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
์ฌ์ฉํ ๋ฐ์ดํฐ ํด๋์ค์ ํ์ฅํจ์๋ก ์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ์ ๋ง๋ค์๋ค. + ์ฐ์ฐ์ plusํจ์๋ฅผ ํธ์ถํด์ ์ปดํ์ผ๋๊ธฐ ๋๋ฌธ์ operator๋ฅผ ์๋ถ์ธ๋ค๋ฉด ๋ฏธ๋ฆฌ ์์ฝ๋ ๋ฉ์๋ ์ด๋ฆ์ธ plus๊ฐ ๊ฒน์น๋ค๊ณ ์๋ฌ๊ฐ ๋์จ๋ค. ์ฝํ๋ฆฐ์ ๋ฏธ๋ฆฌ ์ง์ ๋ ์ฐ์ฐ์๋ง ์ค๋ฒ๋ก๋ฉ ๊ฐ๋ฅํ๋ฉฐ, times(๊ณฑ์ ), div(๋๋์ ), mod(๋๋จธ์ง์ฐ์ฐ), plus, minus ๊ฐ ์๋ค.
๋ฐํ ํ์ ์ด ์์ ๊ฐ์ฒด์ ๋ฌ๋ผ๋ ๊ฐ๋ฅํ๋ค.
operator fun Char.times(count: Int): String {
return toString().repeat(count)
}
ํ๊ฐ์ง ์ ์ํ ๊ฑด ์ฝํ๋ฆฐ์ ๊ตํ๋ฒ์น์ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ 1.5*p, p*1.5๋ ๋ค๋ฅธ ์ฐ์ฐ์๋ฅผ ํธ์ถ ํ ์ ์๋ค.
์ ์๋ ๋ณ์๊ฐ var์ด๋ผ๋ฉด +=, -= ์ ๊ฐ์ ๋ณตํฉ๋์ ์ฐ์ฐ์๋ ์ค๋ฒ๋ก๋ฉ์ด ๋๋ค. ๋ค๋ง ๋ฐํํ์ ์ด ์๋ ๊ฒฝ์ฐ์๋ ์๋ก ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด ์ฐธ์กฐ์ํค๋๋ฐ, ์๋ ๊ฐ์ ๋ด๋ถ๋ฅผ ๋ณ๊ฒฝํ๊ณ ์ถ๋ค๋ฉด Unit์ผ๋ก ๋ฐํ๊ฐ์ ์ฃผ๋ -Assign ์ฐ์ฐ์ํจ์๋ฅผ ์ค๋ฒ๋ก๋ฉํ๋ฉด๋๋ค.
๋ฌธ์ ๋ plus์ plusAssign์ ๋์์ ์ ์ํ๋ค๋ฉด, var ๋ณ์์ ๊ฒฝ์ฐ ๋ชจํธ์ฑ ์๋ฌ๋ฅผ ๋ด๋ฟ๋๋ค. ๋ฐ๋ผ์ val๋ก ์ง์ ํด์ ์ฐ๊ฑฐ๋, ๋์์ ์ ์ํ๋ ์ผ์ ํผํด์ผํ๋ค.
๋จํญ์ฐ์ฐ๋ ์ค๋ฒ๋ก๋ฉ์ด ๋๋๋ฐ, unaryPlus, unaryMinus, inc, dec, not ์ ์ฌ์ฉํ๋ค. ๋จํญ์ด๋ ํ๋ผ๋ฏธํฐ๋ ์๋ค.
operator fun Point.unaryMinus(): Point {
return Point(-x, -y)
}
์ฆ๊ฐ์ฐ์ฐ์์ธ inc, dec์ ๋ณด๋ฉด
operator fun BigDecimal.inc() = this + BigDecimal.ONE
this๋ฅผ ์ด์ฉํด ๊ตฌํํ๋ ๊ฑธ ๋ณผ ์ ์๋ค.
๋ค์์ ๋น๊ต ์ฐ์ฐ์์ธ๋ฐ, equals๋ compareTo๋ฅผ ์ค๋ฒ๋ก๋ฉํ๋ ๊ฒ์ด๋ค. equals๋ Any์ ์ ์๋์ด ์๊ธฐ ๋๋ฌธ์ override๋ฅผ ๋ถ์ฌ์ ์ฌ์ฉํด์ผํ๋ค.
class Point(val x: Int, val y: Int) {
override fun equals(obj: Any?): Boolean {
if (obj === this) return true
if (obj !is Point) return false
return obj.x == x && obj.y == y
}
}
===๋ฅผ ์ด์ฉํด ๋ฉ๋ชจ๋ฆฌ ๊ฐ์ ๋น๊ตํ๋ ๋ฐฉ๋ฒ์ ์ค๋ฒ๋ผ์ด๋ฉ์ด ์๋๋ค. ๋ฐ๋ผ์ if (obj === this) return true ์ด๋ ๊ฒ ๋น๊ตํ๋ ๊ฒ์ด๋ค.
compareTo๋ Comparable ์ธํฐํ์ด์ค์ ์๋ ๋ฉ์๋๋ฅผ ํธ์ถํ๋๋ฐ, ์ฌ์ฉํ ํด๋์ค์์ ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์์ผํ๋ค.
class Person(
val firstName: String, val lastName: String
) : Comparable<Person> {
override fun compareTo(other: Person): Int {
return compareValuesBy(this, other,
Person::lastName, Person::firstName)
}
}
Comparable<T> ์ด๊ธฐ ๋๋ฌธ์ ํ์ ์ ์ง์ ํด์ค์ผํ๋ค.
Collection์์ in์ contains์ ๋์ํ๋ค. ์ปฌ๋ ์ ์์ ์์์ค ํ์ํ ๊ฐ์ ์ ๋ฌด๋ฅผ ์ฐพ์ผ๋ ค๋ฉด in์ ์ฐ๋ฉด ๋๋ค. for์์ ์ฌ์ฉํ๋ in์ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ป๋ ๊ฒ์ด๋ผ์ ์๋ฏธ๊ฐ ๋ค๋ฅด๋ค.
๋ซํ๋ฒ์๋ฅผ ์ง์ ํ ๋๋ง๋๋ ..๋ rangeTo์ ๋์ํ๋ค. Comparable ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ์ํ๋ผ๋ฉด rangeTo๋ ์๋์ผ๋ก ์ง์๋๋ฏ๋ก ๋ฐ๋ก ๊ตฌํํ ํ์๊ฐ ์๋ค. ์ฑ ์ ๋ณด๋ค๊ฐ ์ด๊ฑฐ๋ ์ข ํท๊ฐ๋ฆด๋งํ ๊ฒ ๊ฐ์์ ๊ฐ์ ธ์๋ค
0..n+1
0..(n+1)
๋ ๋ฒ์๋ ๊ฐ๊ฒ ๋์จ๋ค. rangeTo์ ์ฐ์ ์์๊ฐ ๋ฎ๊ธฐ ๋๋ฌธ์ ๊ดํธ๋ฅผ ์ณ์ค ํ์๋ ์์ง๋ง ๊ฐ๋ ์ฑ์ ์ํด ๊ดํธ๋ฅผ ์ฐ๊ฑฐ๋, ๋์ด์ฐ๊ธฐ๋ฅผ ํด์ฃผ๋๊ฒ ์ข๋ค.
destructuring๋ ๋์ํ๋ ๋ฉ์๋๊ฐ ์๋ค.์ปดํ์ผ๋ฌ์์ ๋ณํํ๋ ๋ฉ์๋๋ผ ์ฝ๋์์ ๋ณด์ด์ง๋ ์๋ componentN์ธ๋ฐ N์ ๋ณ์ ์์น์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ ๊ฐ์ด๋ค. ๋ฌดํํ componentN์ ์ ์ธํ ์๋ ์๊ณ , 5๊ฐ๊น์ง ๊ฐ๋ฅํ๋ค.
5๊ฐ๋ฅผ ์ด๊ณผํ๋ฉด
Destructuring declaration initializer of type List must have a 'component6()' function
์ด๋ฐ ์๋ฌ๋ฌธ์ ๋ณด์ฌ์ค๋ค.
for ((key, value) in map) {
println("$key -> $value")
}
์ด๋ฐ ๊ตฌ์กฐ๋ถํด์ ์ธ์ ๋ฃจํ์ map์ ๊ฐ์ด ์ธ๋ ์ฅ์ ์ด ๊ทน๋ํ๋๋ค. ์๋ฐ์์๋ ์๋๋ map ์ดํฐ๋ ์ด์ ์ด ์ฝํ๋ฆฐ์์๋ ๋๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํ ๋ฐฉ๋ฒ์ด๋ค.
์์ ํ๋กํผํฐ delegated property
์ ๋ด์ฉ์ด ์ฐ์ฐ์์ ๋ํ ์ดํด๋ฅผ ๋์ด๋ ๊ฑฐ ์๋ค๋ฉด, ์ด๋ฒ ์ฅ์ ํต์ฌ์ ์ด๊ฑฐ๋ผ๊ณ ์๊ฐํ๋ค. ์์์ ๋์์ธํจํด์์๋ ๋์ค๋๋ฐ ๊ฐ์ฒด๊ฐ ์ง์ ์์ ์ ์ํํ๋ ๊ฒ ์๋๋ผ ์์ ์ ์ฒ๋ฆฌํ๊ฒ ํ๋ ๋์ฐ๋ฏธ ๊ฐ์ฒด๋ฅผ ํธ์ถํ๋ ๋ฐฉ๋ฒ์ด๋ค. ์ด ๋์ฐ๋ฏธ ๊ฐ์ฒด๋ฅผ ์์ ๊ฐ์ฒด๋ผ๊ณ ํ๊ณ ์ฌ๊ธฐ์๋ ํ๋กํผํฐ์ ์ ๊ทผ์์ ๋์ํ๋ค.
class Foo{
private val delegate = Delegate()
var p: Type
set(value: Type) = delegate.setValue(..., value)
get() = delegate.getValue(...)
}
์ ๊ทผ์ p์ ํ์ง๋ง, ์ค์ ๋ก ๊ฐ ์ฒ๋ฆฌ๋ delegate์์ ํ๋ ๋ชจ์ต์ด๋ค. ์ฌ์ฉํ๋ ๋ชจ์ต์ด viewmodel์ ํ๋กํผํฐ๋ฅผ ์ค์ ํ๋ ๊ฒ๊ณผ ๋น์ทํ๋ฐ
private val _answerId = MutableLiveData<String?>()
val answerId: LiveData<String?> = _answerId
backing property๋ผ๋ ๊ธฐ๋ฒ์ด๋ค.
java.beans์ ์๋ PropertyChangeSupport์ setter์ field๋ฅผ ์กฐํฉํด์ ๋ฆฌ์ค๋๋ฅผ ๋ง๋ค ์๋ ์์ง๋ง, ์์ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํด ๋ง๋ค์ด๋ณด๊ฒ ๋ค.
open class PropertyChangeAware {
protected val changeSupport = PropertyChangeSupport(this)
fun addPropertyChangeListener(listener: PropertyChangeListener) {
changeSupport.addPropertyChangeListener(listener)
}
fun removePropertyChangeListener(listener: PropertyChangeListener) {
changeSupport.removePropertyChangeListener(listener)
}
}
class ObservableProperty( // observer๋ฅผ ๊ตฌํํด๋ ๊ฒ.
var propValue: Int, val changeSupport: PropertyChangeSupport
) {
operator fun getValue(p: Person, prop: KProperty<*>): Int = propValue
operator fun setValue(p: Person, prop: KProperty<*>, newValue: Int) {
val oldValue = propValue
propValue = newValue
changeSupport.firePropertyChange(prop.name, oldValue, newValue)
}
}
๋์ฐ๋ฏธ ํด๋์ค์ธ๋ฐ, getValue, setValue๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํด์ ์ ๊ทผ์๋ฅผ ๊ฐ์กฐํ๋ค. ์ด ๋ฐฉ๋ฒ ๋ง๊ณ Delegates.observable์ ์ฐ๋ ๋ฐฉ๋ฒ์ด ๋ ๊ฐ๋จํ์ง๋ง ์ด๋ป๊ฒ ์๊ฒผ๋ ๋ณด๊ธฐ ์ํด ์ด ์ฝ๋๋ฅผ ๊ฐ์ ธ์๋ค. ์ด๋ ์ฌ์ฉ๋ KProperty๋ ์ฝํ๋ฆฐ์์ ํ๋กํผํฐ๋ฅผ ํํํ๋ ํ์ ์ด๋ค. ์ด๋ ๊ฒ ํ๋ฉด get, set์ ํตํด ๊ฐ๋จํ ๊ฐ์ ์ต์ ๋นํ ์ ์๊ฒ๋๋ค. by๋ฅผ ์ฌ์ฉํด ์์ ๊ฐ์ฒด๋ก ์ง์ ํ๋ค. ๊ทธ๋ฌ๋ฉด ์ด์ ์ getter, setter์์ field๋ก ์ ๊ทผํด ์ผ์ผ์ด ์ฐ๊ฒฐํด์ค์ผํ๋ ๊ฑธ ์ปดํ์ผ๋ฌ๊ฐ ํด์ค๋ค.
var age: Int by ObservableProperty(age, changeSupport) // Delegates.observable(age, changeSupport)
var salary: Int by ObservableProperty(salary, changeSupport)
์ด๋ ์ปดํ์ผ๋ฌ์์๋ ObservablePropertyํด๋์ค์ ์ธ์คํด์ค๋ฅผ age์ ํ๋กํผํฐ์ ์ ์ฅํ๊ณ ์ด๊ฑธ delegate, ํ๋กํผํฐ๋ฅผ ํํํ๊ธฐ ์ํ KProperty๋ property๋ก ์์ฑํ๋ค.
์ด๋ฒ์ฅ์ ๋ญ๊ฐ ์ ๋ณด์ ๋์ด๋ค์ด๋ผ๋ ์๊ฐ์ด ๋ ๋ค.
"๋๊ธ, ๊ณต๊ฐ ๋ฒํผ ํ ๋ฒ์ฉ ๋๋ฅด๊ณ ๊ฐ์ฃผ์๋ฉด ํฐ ํ์ด ๋ฉ๋๋ค"
'๐ > ์ฝํ๋ฆฐ ์ธ ์ก์ ๐' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Kotlin in action - ๋ถ๋ก E. ์ฝ๋ฃจํด๊ณผ Async/Await (0) | 2023.10.13 |
---|---|
Kotlin in action(8) (0) | 2023.10.10 |
Kotlin in action(6) (0) | 2023.10.10 |
Kotlin in action(5) (0) | 2023.10.10 |
Kotlin in action(4) (0) | 2023.10.10 |