정수타입 뿐만 아니라 Hashable프로토콜을 따르는 모든 타입을 원시값의 타입으로 지정할 수 있다.
enumSchool:String{caseelementary="초등"casemiddle="중등"casehigh="고등"caseuniversity}// 열거형의 원시값 타입이 String일때, 원시값이 지정되지 않는다면 case의 이름을 원시값으로 사용print("School.middle.rawValue == \(School.middle.rawValue)")// 중등print("School.university.rawValue == \(School.university.rawValue)")// university
원시값을 통한 초기화
rawValue를 통해 초기화 할 수 있다.
rawValue가 case에 해당하지 않을 수 있으므로(3이상의 값) rawValue를 통해 초기화 한 인스턴스는 옵셔널 타입 이다.
letapple:Fruit?=Fruit(rawValue:0)ifletorange:Fruit=Fruit(rawValue:5){print("rawValue 5에 해당하는 케이스는 \(orange)")}else{print("rawValue 5에 해당하는 케이스가 없습니다")}// rawValue 5에 해당하는 케이스가 없습니다
열거형의 메서드
enumMonth{casedec,jan,febcasemar,apr,maycasejun,jul,augcasesep,act,novfuncprintMessage(){switchself{case.mar,.apr,.may{print("봄")}case.jun,.jul,.aug{print("여름")}case.sep,.oct,.nov{print("가을")}case.dec,.jan,.feb{print("겨울")}}}}Month.mar.printMessage()// 봄
개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
인프런, 야곰의 스위프트 기본문법 강좌를 듣고 정리하였습니다.
구조체(struct)
대부분의 타입이 구조체로 이루어져있음 > 타입을 정의 > 값 타입
struct 이름 {
구현부
}
예시는 아래와 같다.
structSample{// 인스턴스 프로퍼티varmutableProperty:Int=100// 가변 프로퍼티letimmutableProperty:Int=100// 불변 프로퍼티// 타입 프로퍼티staticvartypeProperty:Int=100// 인스턴스 메서드funcinstanceMethod(){print("instance method")}// 타입 메서드staticfunctypeMethod(){print("type method")}}
프로퍼티: 구조체 안에 들어가는 인스턴스 변수
메서드: 구조체 안에 들어가는 함수
구조체 사용
// 가변 인스턴스 > 인스턴스에서 사용하는 프로퍼티// Sample이라는 구조체가 타입이 된다.varmutable:Sample=Sample()mutable.mutableProperty=200mutable.immutableProperty=200// 프로퍼티 선언 자체에서 불변으로 선언한 프로퍼티의 값은 변경 불가능하다.// 불변 인스턴스 > 인스턴스에서 사용하는 프로퍼티letimmutable:Sample=Sample()immutable.mutableProperty=100// 가변 프로퍼티로 설정했다고 하더라도 불변 인스턴스의 갑은 변경 불가능하다.// 타입 프로퍼티 및 메서드 > Sample이라는 구조체 타입 자체가 사용할 수 있는 프로퍼티, 메서드Sample.typeProperty=300Sample.typeMethod()// type method// 인스턴스에서 타입 프로퍼티를 사용하는 것은 불가능하다.mutable.typeProperty=400mutable.typeMethod()
예시는 아래와 같다.
structStudent{varname:String="unknown"var`class`:String="Swift"// 타입메서드staticfuncselfIntroduce(){print("학생 타입입니다...")}// 인스턴스 메서드funcselfIntroduce(){print("저는 \(self.class)반 \(name)입니다...")}}Student.selfIntroduce()// 학생 타입입니다...varzehye:Student=Student()zehye.name="zehye"zehye.class="스위프트"zehye.selfIntroduce()// 저는 스위프트반 zehye입니다...letkina:Student=Student()// 불변 인스턴스로 프로퍼티값 변경 불가능kina.name=kinakina.selfIntroduce()// 저는 스위프트반 unknown입니다...
클래스(class)
구조체와 거의 비슷하지만 값타입인 구조체와는 다르게 클래스는 참조타입 이다.
더 나아가, 다중상속이 불가능하다.
class 이름 {
구현부
}
예시는 아래와 같다.
classSample{varmutableProperty:Int=100letimmutableProperty:Int=100staticvartypeProperty:Int=100funcinstanceMethod(){print("instance method")}// 타입 메서드// 상속을 받았을 때, 재정의 불가 타입 메서드 - staticstaticfuncinstanceMethod(){print("type method - static")}// 상속을 받았을 때, 재정의 가능 타입 메서드 - classclassfuncclassMethod(){print("type method - class")}}
클래스
클래스는 구조체와 다르게 let, var로 인스턴스 설정하였다고 하더라도 가변 프로퍼티를 통해 값 변경이 가능하다.
varmutableReference:Sample=Sample()letimmutableReference:Sample=Sample()mutableReference.mutableProperty=300immutableReference.mutableProperty=300// 불변 프로퍼티를 통한 값변경은 당연히 불가능하다.mutableReference.immutableProperty=200immutableReference.immutableProperty=200// 타입 프로퍼티 및 메서드Sample.typeProperty=300Sample.typeMethod()
예시는 아래와 같다.
classStudent{varname:String="unknown"var`class`:String="Swift"classfuncselfIntroduce(){print("학생 타입입니다...")}funcselfIntroduce(){print("저는 \(self.class)반 \(name)입니다...")}}Student.selfIntroduce()// 학생 타입입니다...varzehye:Student=Student()zehye.name="지혜"zehye.class="스위프트"zehye.selfIntroduce()// 저는 스위프트반 지혜입니다...// 구조체와 다르게 가변프로퍼티를 let으로 선언한 인스턴스의 값도 변경이 가능하다.letkina:Student=Student()kina.name="키나"kina.class="스위프트"kina.selfIntroduce()// 저는 스위프트반 키나입니다...
개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
인프런, 야곰의 스위프트 기본문법 강좌를 듣고 정리하였습니다.
Optional
값이 ‘있을 수도, 없을 수도 있음’
letoptionalConstant:Int?=nil//혹은letoptionalConstant:Optional<Int>=nilletsomeConstant:Int=nil// 컴파일 에러 발생
옵셔널이 아닌 상수에 nil값을 할당하려고 하면 컴파일 오류가 발생한다.
Optional은 왜 필요한가?
nil의 가능성을 명시적으로 표현해주는 것
nil의 가능성을 문서화하지 안아도 코드만으로 충분히 표현 가능
문서/주석 작성 시간을 절약
전달받은 값이 옵셔널이 아니라면 nil체크를 하지 않더라도 안심하고 사용 가능
효율적인 코딩이 가능해짐
예외 상황을 최소화하는 안정된 코딩 가능
funcsomeFunction(someOptionalParam:Int?){// ...}funcsomeFunction(someOptionalParam:Int){// ...}someFunction(someOptionalParam:nil)someFunction(someOptionalParam:nil)// 컴파일 에러 발생
컴파일 단계에서도 안전하게 Optional값을 처리 가능하다.
Optional의 표현방식 > ?, !
Implicitly Unwrapped Optional, 암시적 추출 옵셔널 > !
타입 뒤에 !를 표현하는 것
옵셔널 타입 자체는 열거형이기 때문에 switch구문으로 표현이 가능하다.
varoptionalValue:Int!=100switchoptionalValue{case.none:// 값이 없다print("This Optional variable is nil!!")case.some(letvalue):// 값이 들어왔다print("Value is \(value)")}// 기존 변수처럼 사용 가능optionalValue=optionalValue+1// nil 할당 가능optionalValue=nil// 잘못된 접근으로 인한 런타임 오류 발생, 이미 nil값을 할당했기 때문optionalValue=optionalValue+1
일반적인 옵셔널 > ?
varoptionalValue:Int?=100switchoptionalValue{case.none:// 값이 없다print("This Optional variable is nil!!")case.some(letvalue):// 값이 들어왔다print("Value is \(value)")}// nil 할당 가능optionalValue=nil// 기존 변수처럼 사용불가 - 옵셔널과 일반 값은 다른 타입이기 때문에 연산불가optionalValue=optionalValue+1
Optional Unwrapping, 옵셔널 값 추출
옵셔널 값을 어떻게 꺼내서 쓰고 활용하는가?
옵셔널 바인딩(Optional Binding) > if let
강제 추출(Force Unwrapping) > !
옵셔널 바인딩(Optional Binding)
옵셔널 값을 꺼내오는 방법 중 하나로 nil체크 + 안전한 값 추출하다는 특징을 가진다.
값이 있는지 확인해보고 값이 있다면 꺼내오고 없다면 지나간다.
funcprintName(_name:String){print(name)}varmyName:String?=nil// 전달되는 값의 타입이 다르기 때문에 컴파일 오류 발생printName(myName)
전달되는 값의 타입이 다를때마다 컴파일 오류가 발생하기 때문에 if-let을 통해 안전하게 옵셔널 값을 추출하도록 한다.
funcprintName(_name:String){print(name)}varmyName:String!=nilifletname:String=myName{printName(name)}else{print("myname == nil")}// name이라는 상수는 if-let 구문안에서만 사용이 가능하다.// 구문 바깥에서 사용했기 때문에 컴파일 오류가 발생한다.printName(myName)
그리고 여러 옵셔널 변수들을 바인딩할 수 있다. 그러나 해당 변수들에 모두 값이 들어가있어야 한다.
varmyName:String?="zehye"varyoutName:String?=nilifletname=myName,letfriend=youtName{print("\(name) and \(friend)")// youtName이 nil이기 때문에 실행이 안됨}yourName="hana"ifletname=myName,letfriend=youtName{print("\(name) and \(friend)")// 실행됨}
강제 추출(Force Unwrapping)
옵셔널의 값을 강제로 추출
funcprintName(_name:String){print(name)}varmyName:String?="zehye"printName(myName!)// zehye !를 사용함으로써 값을 강제로 추출myName=nilprint(myName!)// 강제추출 시 값이 없으므로 런타임 오류 발생varyourName:String!=nil// 처음 선언시 사용 가능printName(yourName)// 여기서 ! 사용하지 않았어도 강제추출 가능