ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift #16 - Any와 타입 체크, 제네릭스
    Swift의 온도 2021. 1. 27. 02:03

     

    1. Any타입과 타입 변환

     

    - Any, AnyObject

    #강한 타입 체크

     *변수/상수 : 선언할 때 타입 확정

     *다른 타입의 값 대입 금지

     

    #Any, AnyObject

     *가변 타입

     *Any : 모든 타입

     *AnyObject : 모든 레퍼런스 타입

     

    - Any

    #Any

    *Any 타입 선언과 다양한 타입의 값 대입
     
    var anyVar : Any = 2
    anyVar = "b"
    anyVar = MyClass()
     
    *Any를 이용한 다양한 타입의 배열
     
    var anyArray : [Any] = [1"2"3.0]
    cs

     

    #타입에 대한 정보가 없음

     *타입별 메소드, 프로퍼티 사용 불가

     *타입 체크, 타입 캐스팅 필요

     

    #타입 정보 얻기

    type(of:)
    cs

     

    #옵셔널

     *nil 대입하려면 Any?로 선언

     

    - 타입 체크, 변환

    #타입 체크 : is

    *객채의 타입 체크 : is
    *Any, AnyObject 객체 : 타입 검사
    *클래스 상속 : 타입 검사
    *프로토콜 채택 검사
     
    var anyVar : Any = 3
     
    if anyVar is Int {
        print("정수 타입")
    }
    cs

     

    - 타입 변환

    #타입 변환 - as를 사용

     *as : 타입 변환, 타입 변환이 확실한 경우

     *as? : 타입 변환 불가시 nil, 옵셔널

     *as! : 강제 타입 변환, 변환 실패시 에러 발생

     

    #타입 변환

    let anyVal : Any = 3
    let intVal1 = antVal as? int //옵셔널 타입
    let intVal2 = anyVal as! Int //Non-Optional Type
     
    *타입 변환 실패시
     
    let anyVal : Any = 3
    let strVal1 = anyVal asString //변환 실패, nil
    let strVal2 = anyVal as! String //변환 실패, 런타임 에러
     
    *옵셔널 바인딩과 사용
     
    if letVal3 = anyVal asInt {
        print("변환 성공")
    }
    cs

     

    #상속과 타입 변환

    *업 캐스팅(항상 성공) - as 사용
     
    let raz = Cat(0
    let animal = raz as Animal
     
    *다운 캐스팅 - as?, as! 사용
     
    let obj : Animal = Dog()
    let doggy1 = obj as Dog //컴파일 에러
    let doggy2 = obj as? Dog //변환 성공, 옵셔널 타입
    let doggy3 = obj as! Dog // 변환 성공, Non-Optional Type
    cs

     

    - 프로토콜과 타입 체크, 변환

    #프로토콜과 as

    *프로토콜과 타입 채택
     
    protocol Sing {}
    struct Bird : Sing {}
     
    *프로토콜과 채택 확인
     
    let sparrow : Any = Bird()
    sparrow is Sing
     
    *프로토콜로 타입 변경
     
    let singing = sparrow as? Sing
    cs

     

    - 타입 알리아스

    #타입에 이름 주기

    *정의
     
    typealias Century = Int
     
    *사용
     
    var thisEra : Century
    thisEra = 21
     
    *클로저와 타입 알리아스
     
    typealias ResultHandler = (Int-> Void
    func myFunc(arg : Int, handler : ResultHandler) {}
    cs

     

    2. 제네릭스

     

    - 제네릭스

    #Swift와 타입

     *타입에 대한 엄격함

     *같은 기능이지만 다른 타입 -> 타입 별로 작성

     

    #제네릭스(Generics) 프로그래밍

     *타입에 대한 추상화

     *타입별로 작성할 필요 없음

     

    - 제네릭스 사용 예

    #두 종류의 타입 추상화

    *Dictionary : 키와 밸류의 타입 추상화
    *프로토콜 이용
     
    struct Dictionary<Key : Hashable, Value> {
        func updayeValue(_ value: Value, forKey key: Key) -> Value?
        func removeValue(forKey key: Key) -> Value?
    }
     
    *딕셔너리 객체 생성
     
    var intAndStrDic = Dictionary<IntString>()
    var strAndArrayDic = Dictionary<String, [String]>()
    cs

     

    - 제네릭스를 사용하는 함수 작성

    #함수 정의

    *함수 파라미터 타입 추상화
     
    func printValue<T>(_ v : T) {
        print("Value \(v)")
    }
     
    *사용
     
    printValue("a")
    printValue(1)
    printValue(1.3)
    cs

     

    - 제네릭스를 사용하는 타입 작성

    #타입 추상화 타입 작성

    *클래스에 적용
     
    class Hospital<T> {
        func hospitalize(patient : T) {
        print("병원에 입원")
        }
    }
     
    *클래스 사용
     
    var hospital = Hospital<Human>()
    var petHospital = Hospital<Pet>()
    cs

     

    3. 접근 조절

     

    - 접근 조절

    #접근 조절 레벨

     *open : 다른 모듈 접근 가능, 다른 모듈에서 상속 가능

     *public : 다른 모듈 접근 가능, 다른 모듈에서 상속 부락, 같은 모듈 상속 가능

     *internal : 같은 모듈 내에서만 접근 가능, 기본값

     *fileprivate : 같은 소스 파일에서만 접근 가능

     *private : 정의된 블록 내에서만 접근 가능

     

    #접근 조절 단위

     *타입, 메소드, 프로퍼티

     

    4. 연산자

     

    - 연산자 작성

    #객체의 행위

     *메소드

     *연산자

     

    #기존 연산자 정의

     *다른 타입에서 사용자 경험을 그대로

     *point1 + point2

     

    #새로운 연산자 정의

     *기존에 없는 연산자 정의

     

    - 연산자 정의

    #연산자 정의 준비

     

    #피 연산자 개수

     *단항 연산자(Unary)

     *이항 연산자(Binary)

     

    #연산자 위치

     *전위(prefix)

     *중의(infix)

     *후위(postfix)

     

    - 불가능한 연산자

    #연산자 정의가 불가능한 연산자

     *할당 : =-

     *반환타입 : ->

     *주석 : //

     *메소드, 프로퍼티 접근용 점 : .

     

    - 연산자 함수 정의

    #커스터 타입과 연산자 함수 

     *연산자 함수는 타입 메소드로 작성

     *연산자 함수의 이름은 연산자

     *단항 연산자 - 파라미터 1개, 연산자 위치 정보 필요

     *이항 연산자 - 파라미터 2개

     

    - 이항 연산자 정의와 사용

    #이항 연산자 함수 정의

    *타입 메소드, 연산자 함수
     
    struct Point {
        var x : Int
        var y : Int
        static func +(left : Point, right : Point) -> Point {
            return Point(x: left.x + right.x, y: left.y + right.y)
        }
    }
     
    *연산자 사용하기
     
    var p1 = Point(x: 10, y:10)
    var p2 = Point(x: 20, y:20)
    p1 + p2
    cs

    - 단항 연산자 정의와 사용

    #단항 연산자 : 연산자 위치

     *전위 연산자 : prefix perator

     *후의 연산자 : postfix operator

     

    #단항 전위 연산자 작성하기

    extension Point {
        static prefix func -(point : Point) -> Point {
            var another = Point()
            another.x = -point.x
            another.y = -point.y
            return another
        }
    }
    let p1 = Point(x: 10, y: 10)
    let p2 = -p1 // (-10, -10)
    cs

     

    - 비교 연산자

    #커스터 타입의 비교

    * == 연산자
    * Equatable 프로토콜
     
    func ==(Ihs: Self, rhs: Self) -> Bool
    cs

     

    - 내용 비교

    #기능 작성

    extension Size : Equatable {
        static func ==(Ihs: Size, rhs: Size) -> Bool {
            return Ihs.width == rhs.width
                && Ihs.height == rhs.height
        }
    }
     
    *사용
     
    var obj1 = Size(width: 10, height: 10)
    var obj2 = Size(width: 10, height: 10)
    var obj3 = Size(width: 20, height: 20)
     
    obj1 == obj2 // true
    obj1 == obj3 // false
    cs

    'Swift의 온도' 카테고리의 다른 글

    Swift #15 - 에러처리  (0) 2021.01.26
    Swift #14 - 프로토콜, extension  (0) 2021.01.22
    Swift #13 - 클로저  (0) 2021.01.21
    Swift #12 - 구조체와 Enum  (0) 2021.01.20
    Swift #11 - 메모리 관리  (0) 2021.01.19

    댓글