Swift 문법(기본편) - enum, tuple

천성우·2023년 5월 17일
0

iOS_swift_문법

목록 보기
3/3
post-thumbnail

튜플


Tuple(튜플)은 swift에서 제공하는 특별한 성격의 집단 자료형이며, 배열이나 딕셔너리와 달리 여러 가지 타입의 아이템을 저장할 수 있다. 하지만 선언 후에는 값의 추가나 삭제와 같은 변경이 불가능하다

  • 여러 데이터를 하나의 값으로 표현
  • 세부 데이터 접근시 Index 사용으로 하는 접근과 이름으로 접근이 가능합니다
var phone = (os: "iOS", model: "iPhone13 Pro")

phone.0 // "iOS"
phone.os // "iOS"

또, Tuple은 compound type으로 named type 뿐 아니라 같은 compound type을 담을 수 있습니다

named type?? compound type??
named type: ‘이름’이 있는 타입으로 클래스, 구조체, 열거형과 프로토콜 등 이름이 있는 타입
compound type: ‘이름이 없는’ 타입으로 튜플과 함수 등과 같이 이름이 없는 타입을 말합니다

let person = (name: "희재", age: 24, introduction: "저는 낭만보이입니다")
// 1.
let (name, age) = person 
// 2.
let (name, age, introduction, gender) = person

왜 에러가 날까요?

  1. person이란 puple의 요소 수가 다르기 때문에 발생하는 에러로 해당하는 요소의 수를 일치시키면 해결 할 수 있습니다
  2. person이라는 puple에 정의 된 요수 외에 추가적인 변수를 할당하려고 하기 때문에 발생하는 에러입니다. 만약 이 에러를 해결하려면 person이란 puple에 gender 변수를 추가하여 해결할 수 있습니다
let person = (name: "희재", age: 24, introduction: "저는 낭만보이입니다", gender: "남자")

let (name, age, introduction, gender) = person

만약 introduction 값이 필요 없다면 어떤 식으로 표현하면 될까요?

Whildcar Pattern을 사용하여 튜플의 일부 값이 필요없을 때 사용할 수 있다

let person = (name: "희재", age: 24, introduction: "저는 낭만보이입니다", gender: "남자")

let (name, age, _, gender) = person

😒  _ 이게 뭐죠?

Whildcard Pattern으로 ( _ , 와일드카드 식별자 )을 사용하여 ‘이 자리에 올 것이 무엇이든 상관하지마라’ 라는 뜻으로 즉, 와일드카드 식별자가 위치한 곳의 값은 무시하는 것!

let myBody = (height: 175, weight: 75)

if myBody.height > 171 && myBody.height < 174 

아래의 내용을 구현해보세요

  1. 171< 키 < 174, 80 < 몸무게 <85 → print(”류뚱의 비율과 비슷하시군요?”)
  2. 키 = 174, 몸무게 = 85→ print(”류뚱의 몸매시군요?)
  3. 키 상관없이, 몸무게 = 85 → print(”류뚱의 몸무게랑 같군요?”)
  4. 몸무게 상관없이, 키 = 174 → print(”류뚱의 키와 같군요?”)
let myBody = (height: 175, weight: 75)

if myBody.height > 171 && myBody.height < 174 && myBody.weight > 80 && myBody.weight < 85 {
        print("큐티보이와 비율이 비슷하시군요")
}
else if myBody.height == 174 && myBody.weight == 85 {
    print("큐티보이의 몸매시군요?")
}
else if myBody.weight == 85 {
    print("큐티보이와 체중이 같군요")
}
else if myBody.height == 174 {
    print("큐티보이와 키가 같군요?")
}
else{
    print("당신은 큐티보이와 함께 할 수 없습니다")
}

enum


열거형(Enumerations)은 관련된 값으로 이루어진 그룹을 공통의 Type으로 선언해 형 안전성(**type-safety**)을 보장하는 방법으로 코드를 다룰 수 있게 해줍니다. 추가적으로 열거형은 1급 클래스 타입, 계산된 프로퍼티를 제공하거나 초기화를 지정하거나, 초기 선언을 확장하여 사용할 수 있습니다

enum의 기본 형태

// enum 키워드를 사용하여 열거형을 정의합니다
enum Sopt { 
	case iOS
	case design
	case server
}
❗ 각 열거형 정의는 완전 새로운 type을 정의하는 것이니 enum의 이름은 대문자로 시작해야합니다

원시 값?

enum은 각각의 열거형에 rawvalue라는 값을 추가로 지정할 수 있습니다. 주로 String, Integer을 이용하며 원시값을 추가하는 것은 enum 값 옆에 적어 추가할 수 있습니다

원시 값이 없는 열거형

enum Sopt {
	case iOS, design, server
}

원시 값이 있는 열거형

위 예시에서 case를 지정할 때 원시값을 지정해줄 수 있는데 이를 Row Value라고 하며 Roa Value가 될 수 있는 자료형은 Number, Character, String Type 이렇게 3가지 Type이 있다

❗ 위와 같은 타입의 원시 값을 선언하려면 enum선언 시 이름 옆에 Type을 꼭 명시해야합니다
// Number Type을 가지는 열거형, Int 타입을 열거형 선언 시 명시해주면
// 가장 먼저 선언된 case가 0부터 1씩 증가 된 값이 들어감
// 하지만 이 원시 값(RawValue)를 직접 지정해줄 수 있음
// 대신 그 이후 원시 값이 없는 case는 바로 이전 원시 값에서 +1한 값으로 셋팅
enum Ranking: Int {
	case jiyoung     // 0
	case nali        // 1
	case sanggu = 10 // 10
	case game        // 11
}

// Character Type의 경우는 모든 case에 대한 원시 값을 직접 선언해주어야 함
// 만약 하나라도 선언해주지 않을 경우 오류가 남
enum Myname: Character {
	case n = "C"
	case a = "h"
	case m = "e"
	case e = "o"
	case s = "n"
}

// String은 원시 값을 지정하지 않으면 case 이름이 원시 값으로 자동으로 지정 됨
enum Cheon: String {
	case name = "CheonSeongWoo" // CheonSeongWoo
	case gender = "남자"         // 남자
	case age                    // age
}
// 위 코드를 보고 추가 설명을 하자면 name의 rawvalue는 "CheonSeongWoo"입니다

design, iOS, server의 값을 유추해보시오

enum Sopt: Int {
		case plan = 0      // 0
		case design        // 1
		case aos = 10      // 10
		case ios           // 11
		case web = 30      // 30
		case server        // 31
}

Associated Values


enum case에 원시값을 저장할 때 모든 case가 동일한 type의 RawValue를 가져야 하고, case 마다 값은 미리 지정된 한 가지 값만 가질 수 있다는 단점을 보완한 것으로 **튜플 형태**로 원하는 타입을 명시하는 형식으로 작성하여 이 단점을 보완할 수 있다

enum EnumName {
	case caseName1(Type)
	case caseName2(Type, Type, ...)
}

enum CheonApple{
	case iPhone(model: String, color: String, price: Int)
	case macBook(model: String, color: String, price: Int)
	case iPad(model: String)
}

let product: CheonApple = .iPheon(model: "13Pro", color: "SierraBlue", 
																		price: 1342000)

Associated Values를 가지는 enum의 switch

switch product {
	case .iPhone("13Pro", "SierraBlue", 1342000): print("천성우의 아이폰이에용")
	case .iPhone: break
	
}

Associated Values을 이용하여 아래 내용을 코드로 구현해보세요!

import Foundation

enum Sopt {
    case plan
    case design
    case aos
    case iOS(haveMacBook: Bool)
    case web
    case server
}

func soptPart(part: Sopt, name: String){
    switch part{
    case .plan: print("당신은 멋진 기획자가 될거에요!")
    case .design: break
    case .aos: break
    case .iOS(let haveMacBook):
        if haveMacBook {
            print("맥북으로 멋지게 아요코딩하자궁")
        }
        else{
            print("잠깐만! \(part)는 맥북은 필수라는 점~!")
        }
    case .web:print("\(part)\(name) 당신은 최고의 웹 개발자입니다!")
    case .server: break
    }
}

soptPart(part: .iOS(haveMacBook: true), name: "천성우")

<이해가 안되는 부분은 언제든지 물어봐주세요>

  • Sopt 지원자를 분류하는 Enum을 만들겁니다!
  • 지원 파트(part, 이름을 연관값으로 받습니다
  • 각 case 별로 아래 내용을 출력하는 코드를 완성해주세요!
    • 기획(전공상관없이)→ "당신은 멋진 기획자가 될거에요!”
    • 디자인 → break
    • 아요 haveMapBook이란 Bool타입 연관값 추가
      • haveMapBook = true → "맥북으로 멋지게 아요코딩하자궁!”
      • haveMapBook = false → "잠깐만! (part)는 맥북은 필수라는 점~!”
    • 웹 → print("(part)의 (name) 당신은 최고의 웹 개발자입니다!")
    • 서버 → break

어떤 상황에서 enum을 사용하면 좋을까요?

  1. 가독성이 좋은 코드를 작성할 때

  2. 효율적인 코드를 작성할 때

profile
응애 난 애기 개발자..

0개의 댓글