티스토리 뷰
안녕하세요ㅎㅎ
어제 BoostCamp에서 yagom님과 lingostar님이 정말 좋은 swift강의를 해주셨는데요 :)
오늘은 그 강의들을 정리하는 시간을 가져볼려고 해요.
정말정말 좋은 강의였는데, 이 글에 전부 담아 볼 수 있도록 노력해보겠습니다 XD
(야곰님의 블로그는 http://blog.yagom.net에요. iOS프로그래밍과 관련된 글을 많이 쓰셨으니 참고하세요! lingostar님은 따로 블로그가 없으신 것 같아요 ㅠㅠ 찾아봐도 나오질 않네요.)
오늘은 CLASS / STRUCT / ENUM 에 대해서만 볼게요 :)
CLASS / STRUCT / ENUM 타입이 각각 어떤 역할을 하는지, 차이점이 뭔지 혹시 아시나요?
각각 설명해드리겠습니다.
1. CLASS
- 전통적인 OOP 관점에서의 클래스. swift에서는 객체라는 용어대신에 '인스턴스'라는 용어를 사용하는 것 같아요. 한마디로 클래스타입의 인스턴스를 객체라고 칭하지 않습니다. (인스턴스는 특정타입이 메모리에 적재된 시점의 타입)
- 단일 상속만 가능합니다.
- (인스턴스/타입) 메서드, (인스턴스/타입) 프로퍼티
- 참조타입(=reference type) (call by reference)
- iOS 프레임워크의 대부분이 클래스로 구성되어있습니다.
- CLASS와 다르게 상속이 불가능 합니다.
- (인스턴스/타입)메서드, (인스턴스/타입)프로퍼티
- 값타입(=value type) (call by value)
- swift의 대부분의 큰 뼈대는 모두 STRUCT(이하 구조체)로 구성이 되어있습니다.
iOS를 하신다면 이 코드는 정말 많이 보셨다고 생각되는데, 저기 ViewController앞에 class. 보이시나요? 이 ViewController 는 UIViewController를 상속받고 있네요?
UIViewController의 정의부분으로 한번 가볼까요?
자 UIViewController앞에 class. 보이시나요?
이렇게 iOS는 클래스를 상속받아 해당 클래스, 즉 부모클래스에 있는 기능들을 자식클래스에서 쓸 수 있게됩니다.
만약 iOS프레임워크가 구조체였다면 이렇게 쓰지 못하겠죠?
왜냐하면 구조체는 상속이 불가능하기 때문이죠.
그래서 iOS프레임워크에서는 클래스를 사용한다고 할 수 있습니다 :)
그럼? 상속도 안되는 구조체를 왜쓰지..
자 위에서 swift의 대부분의 큰 뼈대는 구조체라고 그랬죠?
이 '대부분의 큰 뼈대'는 무엇을 의미할까요?
예시 하나로 들면 이해가 빠르실 것 같아 예시를 하나 들고왔어요 :)
우리가 정말 자주쓰는 Int, Double, String...
이 타입들이 어떻게 구현되어있을 것 같으세요?
command키를 눌러 정의부분으로 가봅시다 :)
public struct Int : SignedInteger, Comparable, Equatable
public struct Double
public struct String
..
struct가 보이시나요? 이런 데이터 타입들은 구조체로 구현이 되어있답니다 :)
public struct Int : SignedInteger, Comparable, Equatable
- 다른 언어의 열거형과는 많이 다릅니다! ( 기존에 본인이 알고있던 언어의 열거형과 동치시키며 생각하지마시고 새로운 열거형을 배운다고 생각해주세요 :) )
- 상속이 불가능합니다.
- (인스턴스/타입)메서드, (인스턴스/타입)연산 프로퍼티
enum Animal {
case tiger
case leopard
case lion
}
let tiger2: Animal = Animal.tiger
let lion2: Animal = .lion
tiger2라는 변수는 Animal타입을 가지고 Animal.tiger라는 값을 주었죠.
lion2도 마찬가지입니다. tiger2는 Animal.tiger라고 쓰고 lion2는 그냥 .lion이라고 써주었죠? 사실 둘은 똑같은 의미를 가진답니다. 처음 변수를 선언할 때 이 아이는 Animal타입이야~ 라고 컴파일러에게 힌트를 주었으므로 또 Animal.tiger라고 쓸 필요 없이 그냥 .lion만 써도 컴파일러는 알아듣게 되는 것이죠.
print(tiger2)
print(lion2)
를 하면 어떻게 될까요?
tiger
lion
이 나오게 됩니다. 값을 주지 않아도 이름 그자체로서 값을 의미한다고 볼 수 있겠네요. C나 C++에서는 아무 값도 할당해주지 않았으니 0과 1이 나왔겠죠? ㅎㅎ
이렇게까지 보시고 이런생각이 드실 수 있어요.
"아, 나는 swift에서 C나 C++에서 사용하는 열거형을 쓰고싶은데"
그러시고 싶으시다면, 방법이 있습니다.
바로 raw value를 설정하는 것 입니다.
raw value가 뭘까요? 의미 그대로 '원시값'입니다.
위의 예제에서 원시값을 넣어볼까요?
enum Animal : Int {
case tiger = 0
case leopard
case lion
}
Animal타입은 Int타입을 상속하는것은 아니고 ㅎㅎ.. : Int타입이라고 타입을 지정해주는 거에요.
자, tiger에게 0이라는 원시값을 할당해주었죠?
print(tiger2.rawValue)
print(lion2.rawValue)
(tiger2와 lion2는 위에서 선언해준 Animal타입 상수입니다.)
를 하면 값이 어떻게 나올까요?
0
2
이렇게 나오게 된답니다. leopard에게는 1이 할당되었겠죠?
자 Double형으로도 한번 해볼까요?
enum Animal : Double {
case tiger = 0
case leopard
case lion
}
print(tiger2.rawValue)
print(lion2.rawValue)
을 하면 뭐가 출력될까요?
바로
0.0
2.0
가 출력되게 됩니다. Double이니 소수점으로 출력이 된 것이겠죠?
자, 그럼 원시값을 0이 아닌 0.1로 줘볼까요?
enum Animal : Double {
case tiger = 0.1
case leopard
case lion
}
이렇게요!
그럼 어떤일이 발생하시나요?
컴파일러가 오류가 발생했다고 말해줍니다.
이렇게 말이죠.
자 오류를 해석해봅시다!
"이전의 원시값이 정수가 아닐 경우 enum case의 원시값을 정의해주어야 합니다"
이게 무슨 뜻일까요?
앞 case tiger에서 0.1을 원시값으로 지정해주었죠?컴파일러는 leopard의 원시값을 어떤 값으로 줘야할지 몰라서 나는 에러입니다. 1을 주어야 할지, 1.1을 주어야 할지 컴파일러는 모르겠죠?
열거형 타입을 String으로 해주어 봅시다!
enum Animal : String {
case tiger = "A"
case leopard
case lion
}
print(tiger2.rawValue)
print(lion2.rawValue)
결과가 뭐가 나오실 것 같나요?
A
C
라고 생각하셨나요?
사실 해보기 전까지 저도 A와 C가 나올 줄 알았답니다 :)..
콘솔에는
A
lion
이 나왔어요.
"열거형은 이름 그 자체만으로 의미를 가진다"라는 점에서 (이름이 String이니까) 이렇게 나오지 않았나 싶어요 :)
스위프트 개발문서의 열거형쪽을 읽어보시면,
원시 값은 문자열, 글자, 정수 또는 어떠한 부동 소수점 타입이 될 수 있습니다.
각각의 원시 값은 열거형 정의 안에서 반드시 유일해야 합니다.
원시 값으로 정수가 사용되었다면, 열거형 멤버의 일부에 아무 값도 설정되지 않은 경우 자동 증가(Auto-incrementation)할 것입니다.
답이 A와 C로 나오지 않은 이유를 알겠네요! :)
정수가 아니라서 입니다 ㅎㅎ..
원시값은 정수값만을 할당해야만 1씩 증가하게 된답니다 :)
자 또한 열거형에서 알아두셔야 할게 있어요.
"전달한 원시값에 해당하는 케이스가 없을 수 있기 때문에 원시값을 통한 인스턴스 생성은 옵셔널값으로 반환된다."
예제를 통해 확인해 볼까요?
enum Animal : Int {
case tiger = 0
case leopard
case lion
}
tiger에게 0을 할당했으니 leopard는 1, lion은 2가 되겠죠?
자 그럼
let someAnimal = Animal(rawValue: 4)
이 코드는 무엇을 의미할까요?
"Animal열거형에 원시값 4를 가지는 애를 someAnimal에 넣어줘"가 될 것 같아요 :)
근데 Animal열거형에는 2까지 밖에 없죠?
print(someAnimal)
를 하면 어떻게 될까요?
nil
이 출력되게 된답니다 :) 신기하죠? 그러면 someAnimal은 optional타입이겠네요!
자 이렇게 CLASS / STRUCT / ENUM을 정리해보았는데 어떠신가요?
다음 글에서는 이 CLASS / STRUCT / ENUM을 언제 쓰면 좋을지에 대해서 정리해볼려고 해요!!!
지적은 환영입니다. 🙏
'Swift' 카테고리의 다른 글
Swift3 ) Swift로 선택정렬(Selection Sort)짜보기 (2) | 2017.05.12 |
---|---|
Swift3 ) swift3에서 나머지 구하기 / %사용하기 (0) | 2017.02.21 |
swift3 ) Optional 개념 정리 (23) | 2017.01.25 |
Swift ) Swift 기초문법2 ( CLASS / STRUCT / ENUM ) (2) | 2017.01.23 |
Swift3 ) Dictionary에서 print순서 (0) | 2017.01.23 |
- IOS
- fastlane
- 회고
- 피아노
- Combine
- Accessibility
- swift sort
- SwiftUI
- swift delegate
- 제이슨 파싱
- github
- Git
- FLUTTER
- WWDC
- iOS delegate
- WidgetKit
- 스위프트
- WKWebView
- np-hard
- Xcode
- swift 공부
- swift tutorial
- swift array
- np-complete
- ios 13
- actor
- Swift
- swift3
- 스위프트 문법
- UIBezierPath
- Total
- Today
- Yesterday