10
10

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
COMMENT