Byzz91
7/21/2019 - 12:02 PM

.? !! ?: Elvis Operator

.? !! ?: Elvis Operator

package my.demo

/**
 * 모든 참조 변수가 Null 값을 가질 수 있는 자바와 달리, 코틀린의 참조 변수는 기본적으로 null 값을 가질 수 없는 `Non-null` 타입!
 *
 * ### null이 반활 되는 경우가 더 자연스러운 경우
 *
 * 비트맵 이미지를 만들어 반환하는 CreateBitmap() 함수의 경우, 반환 값이 생성된 Bitmap 객체여야 하겠지만,
 * 내부적으로 이미지 생성에 실패한 경우 생성되지 않은 Bitmap 객체를 반환하는 것 보다 Null을 반환하는 것이
 * 대응하기에 훨씬 유리하다.
 */

class Bitmap(val width: Int, val height: Int) {
    val size: Int
    get() = width * height

//    init {
//        size = width * height
//    }
    val map = ByteArray(size)
}

fun CreateBitmap(width: Int, height: Int): Bitmap? {
    if (width > 0 && height > 0) return Bitmap(width, height)
    else return null
}

/**
 * Safe Call의 장점 예시
 */
class Address(val st: String, val zipCode: Int, var city: String)
class Company(val name: String, val addr: Address?)
class Person(val name: String, val company: Company?)

fun main(argv: Array<String>) : Unit {
    val bitmap: Bitmap? = CreateBitmap(-1, 10)

    println(bitmap?.size)

    if (bitmap != null) {
        println(bitmap.size)
        println(bitmap.map)
    }

    /**
     * 절대 null이 아니야 `!!` 연산자
     */
    println(bitmap!!.size)

    // 안전한 호출(Safe Calls) 연산자
    // 안전한 호출 연산자는 `?.`로 표시하며 아래와 같이 사용한다
    fun Person.cityName(): String {
        val city: String? = this.company?.addr?.city
//        if (city != null) return city else "Unknown"
//        return city ?: "Unknown"

        return this.company?.addr?.city ?: "Unknown"
    }

    /**
     * Elvis Operator (?:)
     *
     * 왼쪽값이 null 이면 오른쪽 값
     */
    fun Person.cityName2(): String = this.company?.addr?.city ?: "Unknown"

    val person = Person("monguse", null)
    person.company?.addr?.city = "Seoul" // 안전한 호출의 연산자는 식의 왼쪽에도 사용될 수 있다.
}