Swift 구조체와 enum

  1. 구조체란? 프로그래밍 언어에서 의미가 연결된 한 덩어리로 처리하는 방식으로 클래스처럼 프로퍼티와 메소드로 구성된다.
    1. 구조체와 클래스의 관계
      1. 구조체와 클래스에 모두 있는 것
        1. 프로퍼티와 메소드
        2. 초기화(Initializer)
      2. 구조체에는 없고 클래스만 있는 것
        1. 상속
        2. 재정의
        3. ARC(Automatic Reference Count)
      3. 구조체와 클래스의 속성
        1. 클래스는 레퍼런스 타입
          1. 클래스의 경우 객체를 대입하면 참조 추가로 동작하여 한 객체의 속성 값을 공유하게 된다.
          2. 아래는 레퍼런스 타입의 객체 공유를 나타내는 그림이다.
          3. 위에서 obj1과 obj2가 동일한 클래스를 가진 객체라면 obj2 = obj1으로 객체를 대입하게 되면 하나의 객체를 가리키게 되고, 둘 중에 하나라도 값을 변경하면 나머지 하나도 변경된 값으로 반영된다.
        2. 구조체는 밸류 타입
          1. 구조체의 경우 객체를 대입하게되면 복사가 되어 한 객체의 속성 값이 바뀌어도 다른 객체의 속성 값은 변경되지 않는다.
          2. 아래는 밸류 타입의 객체 복사를 나타내는 그림이다.
          3. 위에서 obj1과 obj2가 동일한 구조체를 가진 객체라면 obj2 = obj1으로 객체를 대입하게 되면 객체가 복사가 되어 또 다른 객체를 만들게 되며, 한 객체의 값을 변경해도 다른 객체에는 영향을 주지 않는다.
    2. 구조체의 정의
      1. 정의 방법 : struct[구조체 이름]{ // 프로퍼티, 메소드 구현}
      2. 구조체의 객체 생성과 사용
        구조체의 객체 생성과 사용
        // 구조체 정의
        struct Point {
            var x = 0
            var y = 0

            func description() -> String {
                return "Point : \(x), \(y)"
            }
        }

        // 구조체 생성
        var point = Point()
        point.x = 10
        point.y = 20
        // 해당 부분은 var point = Point(x : 10, y : 20) 가능
        // => 구조체에서는 프로퍼티를 자동으로 초기화한다.
        print(point.description())
      3. 구조체의 초기화(Initializer)
        1. 초기화가 필요한 프로퍼티 정의
          초기화가 필요한 프로퍼티 정의
          // 구조체 정의
          struct Point {
              var x : Int
              var y : Int

              func description() -> String {
                  return "Point : \(x), \(y)"
              }
          }

          // 구조체 생성
          var point1 = Point() // 에러 발생
          // init(x : Int, y : Int) 가 있는 것과 동일한 상태
          var point2 = Point(x : 10, y : 20)
        2. Initializer 정의
          구조체에 Initializer 정의
          // 구조체 정의
          struct Point {
              var x : Int
              var y : Int

              init() {
                  self.x = 0
                  self.y = 0
              }
          }

          // 구조체 생성
          var point1 = Point()
          var point2 = Point(x : 10, y : 20) // 에러 발생
          // Initialize 정의 시는 프로퍼티 자동 초기화는 되지 않음
      4. 구조체의 프로퍼티 수정
        1. 초기화 메소드에서 설정 가능
        2. 구조체 외부에서 설정 가능
        3. 구조체 내부에서 변경 시 메소드 선언에 mutating 키워드 추가 후 설정 가능
        4. 구조체의 프로퍼티 수정은 아래와 같다.
          구조체의 프로퍼티 수정
          // 구조체 정의
          struct Point {
              var x : Int
              var y : Int
              // 초기화 메소드 사용
              init() {
                  self.x = 0
                  self.y = 0
              }
           
             // 구조체 내부에서 설정
             mutating func moveTo(x : Int, y : Int) {
                 self.x = x
                 self.y = y
             }
          }

          // 구조체 생성
          var point = Point()
          // 구조체 외부에서 설정
          point.x = 10
          point.y = 20
  2. Enum이란? 열거형 타입으로 원소를 정의하여 그 원소 내에서만 사용하는 데이터 타입의 일종으로 enumeration 에서 따왔다.
    1. Enum 정의
      Enum 정의
      // Enum 정의
      enum Pet {
         case cat
         case dog
         case bird
      }

      enum Week : Int {
          case sun, mon, tue, wed, thur, fri, sat
      }
      // Int 형으로 정의 시 sun은 0이며, 하나씩 증가하게 된다.
      // mon = 1, tue = 2, ...

      enum Day : String {
          case am = "오전"
          case pm = "오후"
      }
      // Int 형 이외에는 값을 반드시 넣어주어야 한다.
    2. Enum 사용
      Enum 사용
      // Enum 정의
      enum Pet {
         case cat
         case dog
         case bird
      }
      // enum 객체 정의
      var pet : Pet
      pet = Pet.cat
      pet = Pet.dog
      pet = Pet.other // 없는 값이므로 에러 발생

      // enum은 주로 Switch 문과 사용
      switch pet {
      case Pet.cat :
              print("고양이")
      case .dog :
              print("강아지")
      case .bird :
              print("새")
      }

      // enum의 원소의 값 얻기
      pet.rawValue // dog를 얻을 수 있음

    3. Enum의 계산 프로퍼티와 메소드
      Enum 사용
      // Enum 정의
      enum Pet {
         case cat
         case dog
         case bird

         // 계산 프로퍼티 정의
         var name : String {
               switch self {
               case .cat : return "고양이"
               case .dog : return "강아지"
               case .bird : return "새"
               }
         }

         func description() -> String {
              return self.name
         }
      }
      // enum 객체 정의
      var pet : Pet
      pet = Pet.cat
      print(pet.description()) // 고양이 출력
      pet = Pet.dog
      print(pet.description()) // 강아지 출력