안녕하세요! 짭짭이 입니다.
이전 보다 좀 더 빠르게 돌아왔습니다.
추석인데,,, 추석이 지나가고 있어서 슬픕니다 ㅠㅠ
8일 동안 쉬는데 ㅠㅠ 행복한데 ㅠㅠ
요즘엔 웹도 공부하고 있는데, 나중에 허접하지만 웹도 올려보도록 하겠습니다.
https://www.youtube.com/watch?v=tLcynwlNh38
< Young K 노래 입니다 ㅎㅎㅎㅎ 노래방에서 부르고 싶은데 없네요,,,,>
1. 값으로서의 Enum
struct UserInfo{
let id : String
let name : String
}
enum Message {
case join(UserInfo , Date)
case text(UserInfo , String , Date)
case quit(UserInfo, Date)
}
let defaultUser = UserInfo(id: "2015", name: "Zico")
let join : Message = .join(defaultUser, Date())
let text = Message.text(defaultUser, "Hello world", Date())
let quit : Message = Message.quit(defaultUser, Date())
Enum은 그냥 Case로만 나누는게 아니라 값으로서 값을 가질 수 있습니다.
그래서 아래 처럼 분류가 할 수 있습니다.
func userState(message : Message) {
switch message{
case .join(let userinfo, let date): (1)
print("Join User : id -> \(userinfo.id) name -> \(userinfo.name) \n Date : \(date)")
case let .text(userinfo, message, date): (2)
print("Text User : id -> \(userinfo.id) name -> \(userinfo.name) \n Date : \(date) \n Message : \(message)")
case .quit(_ : let userinfo, _ : let date): (3)
print("Quit User : id -> \(userinfo.id) name -> \(userinfo.name) \n Date : \(date)")
}
}
userState(message: join)
// result
Join User : id -> 2015 name -> Zico
Date : 2021-09-21 13:54:12 +0000
userState(message: text)
//result
Text User : id -> 2015 name -> Zico
Date : 2021-09-21 13:54:12 +0000
Enum은 다음 처럼 Switch 문으로 케이스를 분류 해야하고 값이 존재한다면 다음 처럼 (1) ~ (3) 처럼 값을 사용 할 수가 있습니다.
그리고 이런 방식을 사용하면 쉽게 분류 할 수 있고 그 값을 읽어 올 수 있게 됩니다.
** 참고 **
enum Temp{
case number(String)
}
func userStateWithIfCase(message : Message){
(1) if case .join(let userInfo, let date ) = message {
print("[IfCase]Join User : id -> \(userInfo.id) name -> \(userInfo.name) \n Date : \(date)")
}
(2) if case let .text(user ,message ,sendTime) = message{
print("[IfCase]Text User : id -> \(user.id) name -> \(user.name) \n Date : \(sendTime) \n Message : \(message)")
}
if case .number(let input) = Temp.number("Hello"){
print(input)
}
}
userStateWithIfCase(message: join)
//결과
[IfCase]Join User : id -> 2015 name -> Zico
Date : 2021-09-21 13:54:12 +0000
Hello
Case에 대한 분류는 if case 문으로 해줄 수도 있습니다.
분류 방식은 (1) ~ (2) 처럼 해줄 수 있고 message의 값이 .join과 같아면 {} 안의 내용을 수행 한다 입니다.
2. 상속의 대체제
- 상속의 문제점 -
class Human{
let name : String
let id : String
init(name : String , id : String){
self.name = name
self.id = id
}
func display(){
print("\(name) / \(id)")
}
}
class Student : Human{
let school : String
let grade : String
init(school : String , grade : String , name : String , id : String){
self.school = school
self.grade = grade
super.init(name: name, id: id) // Swift는 super.init()이 자신 클래스 정의 후 와야한다.
}
override func display() {
super.display()
print("\(school) \(grade)")
}
}
class Worker : Human{
let company : String
let pay : Int
init(company : String , pay : Int, name : String, id : String){
self.company = company
self.pay = pay
super.init(name: name, id: id)
}
override func display() {
super.display()
print("\(company) \(pay)")
}
}
let humans : [Human] = [
Student(school: "Yale", grade: "Junior", name: "A", id: "2020"),
Worker(company: "LG", pay: 4600, name: "B", id: "1090")
]
func displayAll(people : [Human]){
people.forEach({ human in
human.display()
print("=============")
})
}
displayAll(people: humans)
//결과
A / 2020
Yale Junior
=============
B / 1090
LG 4600
=============
// => 이런 상황인데, 만약 let name : String let id : String가 모두 각각의 클래스로 이동한다면 대대적인 공사가 발생한다.
//이런 상황일 때 Enum을 이용하면 극복이 가능하다.
위에는 상속방식으로 구조화 한 것 입니다.
해당 방식은 다형성을 가질 수 있다, 중복된 코드를 없앨 수 있다 등
상속의 큰 장점을 가질 수 있지만, 경직된 구조화가 된다는 문제가 됩니다.
예를 들어 문서 변경으로 Human의 id가 개별 프로퍼티로 내려와야한다면
다 변경해야합니다. 아주 쉣입니다.
- Enum으로 해결 -
//이런 식으로 Enum case로 종속성을 만들 수도 있다.
//다만 이런 방식은 공통 부분에 대해서 처리를 할 수 없다는 점
//그리고 display와 같은 역할을 override가 아니라 분기 처리로 해결해야한다는 점
//그러나 경직된 구조가 아니라 자유롭게 생성할 수 있다는 점이 큰 장점이다.
enum HumanEnum {
case student(StudentEnum)
case worker(WorkerEnum)
}
struct StudentEnum{
let name : String
let id : String
let school : String
let grade : String
}
struct WorkerEnum{
let name : String
let id : String
let company : String
let pay : Int
}
let humansEnum : [HumanEnum] = [
.student( StudentEnum(name: "A", id: "2020", school: "Yale", grade: "Junior") ) ,
.worker( WorkerEnum(name: "B", id: "1090", company: "LG", pay: 4600) )
]
extension HumanEnum{
func display(){
switch self{
case let .student(student):
print("Student \(student)")
case let .worker(worker):
print("Worker \(worker)")
}
}
}
for human in humansEnum{
human.display()
}
//결과
Student StudentEnum(name: "A", id: "2020", school: "Yale", grade: "Junior")
Worker WorkerEnum(name: "B", id: "1090", company: "LG", pay: 4600)
Enum에 각각의 Case에 객체를 넣어서 값으롤 만들고 Enum에 함수를 만들어서 분기처리로 다형석 짝퉁을 만들어 줍니다.
위와 같은 방식은 확실히 상속의 장점을 살릴 수 없습니다.
하지만 경직된 구조가 아닌 구조화를 할 수 있습니다.
3. RawValue의 Enum
enum FoodType : String{ //Enum에 String을 넣어주면 해당 case가 String의 RawValue를 가지게 된다.
case korean
case japan
case china
// 실패할 경우, nil을 반환하는 초기화 메소드
init?(rawValue: String) {
switch rawValue.lowercased() {
case "kimch" , "bulgogi" :
self = .korean
case "ramen" :
self = .japan
case "trash" :
self = .china
default :
return nil
}
}
}
func returnFoodType(food : String) {
guard let type = FoodType(rawValue: food) else{
print("음식이 없어요")
return
}
print(type)
}
returnFoodType(food: "kimch")
//결과
korean
이렇게 RawValue로 Enum을 사용하면 분기 처리를 좀 더 구조적으로 할 수 있습니다.
지금까지 Enum에 대해 알아봤습니다.
정말 Swift에서는 Enum을 취미로 잘 사용해서,,,, 많이 알아 둬야할 것 같습니다.
감사합니당~~~
'Xcode > Swift - PlayGround' 카테고리의 다른 글
PlayGround) Opeation Queue - 1 (0) | 2022.01.17 |
---|---|
PlayGround) URLSessionDownload를 이용해서 PDF 파일 다운로드 (0) | 2021.12.26 |
PlayGround) Notification Center의 사용법 (0) | 2021.09.03 |
PlayGround) RxMvvm에서 Input과 Output에서 의문점 (0) | 2021.09.03 |
(Swift) Closure - Capturing Value (0) | 2021.09.03 |
댓글