티스토리 뷰

목차

    반응형

    ■ 플로우 기반 형변환 (smart casts)


    안드로이드 코틀린의 장점 중 하나인 Smart Casts는 타입 체크와 명시적 캐스트를 진행합니다.

    자동으로 형변환을 실행하므로 사용자 편의성이 증가합니다.


    if 문에서 null 체크하거나 is 연산자 유형을 검사하면 자료형이 자동으로 변환됩니다.



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    open class Animal {}
    class Cat: Animal() {
        fun nyaa() { println("nyaa") }
    }
    class Dog: Animal() {
        fun wan() { println("wan") }
    }
     
    fun speak(animal: Animal) {
        if (animal is Cat) { animal.nyaa() }
        if (animal is Dog) { animal.wan() }
    }
    fun speak2(animal: Animal?) {
        if (animal == null) {
            println("null")
            return
        }
        speak(animal)
    }
     
    fun main(args: Array<String>) {
        speak2(Cat()) // nyaaと出る
        speak2(Dog()) // wanと出る
        speak2(null// nullと出る
    }
    cs



    speak2 null 체크 결과는 return입니다. if 이후는 Animal?대신 Animal에 되어 있어 speak가 호출할 수 있습니다.


    speak의 if then 절 부분에서는 is에 의한 연산 결과가 존재합니다. 그래서 캐스팅된 서브 클래스 Cat, Dog에 전용 함수를 호출 할 수 있습니다.

     코드(안드로이드 코틀린)의 Swift 버전은 아래와 같습니다.



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    class Animal {}
    class Cat: Animal {
        func nyaa() { print("nyaa") }
    }
    class Dog: Animal {
        func wan() { print("wan") }
    }
     
    func speak(animal: Animal) {
        if let animal = animal as? Cat { animal.nyaa() }
        if let animal = animal as? Dog { animal.wan() }
    }
    func speak2(animal: Animal?) {
        guard let animal = animal else {
            print("null")
            return
        }
        speak(animal)
    }
     
    func main() {
        speak2(Cat())
        speak2(Dog())
        speak2(nil)
    }
     
    main()
    cs



    speak2에서는 Smart casts를 위해 일부러 guard 키워드를 사용하지 않으면 안됩니다. speak, speak2 함께 let animal = 부분이 중복됩니다.


    if 괄호를 생략할 수 있는 것은 좋네요.

    Java는 아래처럼 구현할 수 있습니다.



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    import java.util.*;
    import java.lang.*;
    import java.io.*;
     
    class Animal {}
    class Cat extends Animal {
        void nyaa() { Ideone.print("nyaa"); }
    }
    class Dog extends Animal {
        void wan() { Ideone.print("wan"); }
    }
     
    class Ideone
    {
        public static void print(String str) { System.out.println(str); }
     
        static void speak(Animal animal) {
            if (animal instanceof Cat){
                Cat cat = (Cat)animal;
                cat.nyaa();
            }
            if (animal instanceof Dog) {
                Dog dog = (Dog)animal;
                dog.wan();
            }
        }
        static void speak2(Animal animal) {
            if (animal == null) {
                print("null");
                return;
            }
            speak(animal);
        }
     
        public static void main (String[] args) throws java.lang.Exception
        {
            speak2(new Cat());
            speak2(new Dog());
            speak2(null);
        }
    }
    cs



    null 체크에 관해서는 코드가 올바르다는 전제하에 실행할 수밖에 없습니다. 그리고 speak 대해서는 Cat, Dog를 각각 3회 작성됩니다. (캐스트 전용 함수를 만들면 2회 + null 체크 할 수 있지만요)


    안드로이드 코틀린 Smart casts 소스, Swift Java 비교[안드로이드 코틀린의 장점 중 하나인 Smart casts]



    관련 글

    2019/07/06 - 안드로이드 코틀린 장점, 쉬운 도입과 자바 연계성

    2017/04/07 - JNI (자바 네이티브) 자료형 비교 설명 (Java native 표)

    2017/02/08 - 자바 코딩 규칙, 코드 컨벤션 (Code 스타일과 표준)



    ⓒ written by vicddory

    반응형