오늘도 문법주간으로 주말에 못본 문법강의들을 다 몰아서 봤지만 시간적인 이슈로 따로 TIL을 작성을 못해서 한번에 정리할려고 한다.
열거형은 Swift에서 특정 주제나 종류에 따라 묶을 수 있는 값들을 그룹화하고 정의하여 데이터타입으로 사용할 수 있다.
enum
특징
enum
키워드와 코드블록을 사용하여 정의할 수 있다.case
를 사용하여 정의할 수 있다.데이터 타입
으로 사용할 수 있다.enum
을 사용하여 만들어진 인스턴스는 Value Type
이다.enum 기본 선언 방법 및 사용 방법
// enum 뒤에 열거형의 이름을 작성하고 코드블록 안에서 그룹화된 값들을을 case로 작성한다.
// 기본 선언 방법
enum Season {
case spring
case summer
case autumn
case winter
}
// 한국말로 풀어보기
// Season enum을 선언한다.
// Season이 그룹화하여 갖고있는 값은 spring, summer, autumn, winter 다.
// 기본 사용 방법
// 기본적인 접근 방법
Season.spring // Enum의 이름뒤에 .을 찍고 데이터에 접근할 수 있다.
Season.summer
// 데이터 타입(String, Int ...) 처럼 변수나 상수에 저장할 수 있다.
var season: Season = .spring // 데이터 타입을 Season이라고 명시한다면
// Season.spring에서 Seaspn을 생략할 수 있다.
var summer = Season.summer // 데이터타입을 명시해서 값을 넣으면
// 컴파일러가 데이터 타입을 추론해준다.
summer = .spring // summer의 타입이 Season으로 판단되어
// Season.spring에서 Season을 생략할 수 있다.
enum
Associated Values(연관 값)
case
와 함께 타입을 지정하여 선언하면 연관값을 가질 수 있다.Assoicated Value
기본 선언 방법 및 사용 방법// 선언 방법
// 택배 배송 상태를 관리하는 열거형
enum DeliveryStatus {
case ordered // 주문함
case shipping(trackingNumber: String) // 배달중의 상태로 연관값으로 String형태의 trackingNumber를 저장한다.
case delevereCompleted(date: String) // 배달완료 상태로 연관값으로 String 타입의 date 정보를 저장한다.
}
let status = DeliveryStatus.shipping(trackingNumber: "123")
print(status) // shipping(trackingNumber: "123")
switch status { // status 값을 switch 코드블록에 넣는다.
case .ordered: // .ordered 상태일 때 아래 코드를 실행한다.
print("주문완료!")
case .shipping(let trackingNumber): // .shipping 상태일 때 아래의 코드를 실행한다. 연관값은 trackingNumber 상수에 넣는다.
print("배송중! 송장번호: \(trackingNumber)")
case .delevereCompleted(let date): // .delevereCompleted 상태일 때 아래의 코드를 실행한다. 연관값은 date 상수에 넣는다.
print("배송완료! 배송일: \(date)")
}
enum
Raw Values (원시 값)
case
마다 기본으로 설정된 원시값을 저장할 수 있다.enum
이름 뒤에 콜론:
을 작성한 후 타입을 명시해주어야 한다.case
뒤에 =
을 사용하여 원시값을 정해줄 수 있다.Raw Values
사용법// 문자열의 Raw Value
// 이름(Season)뒤에 : String을 붙여줘서 원시값을 String이라고 명시했다.
enum Season: String {
case spring = "값을 정해줄 수 있다"
case summer // 값이 없다면 case 이름과 동일하게 된다.
case autumn
case winter
}
// 사용 방법
let season = Season.spring
print(season.rawValue) // "값을 정해줄 수 있다"
let season2 = Season.summer
print(season2.rawValue) // "summer"
// 반대로 rawValue를 가지고 Season 상수(변수)를 만들 수 있다.
let newSeason = Season(rawValue: "summer")
print(newSeason) // Optional(summer)
// 숫자형의 Raw Value
enum Month: Int {
case january = 1 // 값을 정해주지 않는다면 0부터 1씩 올라간다.
case february = 3
case march // 값을 정해주지 않아서 3 다음에 4가 된다.
case april // 값을 정해주지 않아서 5가 된다.
case may
case june
case july
case august
case september
case october
case november
case december
}
print(Month.january.rawValue) // 1
print(Month.february.rawValue) // 3
print(Month.march.rawValue) // 4
print(Month.april.rawValue) // 5
let month = Month(rawValue: 3)
print(month) // Optional(february)
enum
에서 함수를 정의하고 사용하는 방법.
// enum 안에 함수를 만들고 호출해서 사용할 수 있다.
enum Season: String {
case spring
case summer
case autumn
case winter
func weather() -> String{
switch self {
case .spring:
return "따뜻해요"
case .summer:
return "더워요"
case .autumn:
return "시원해요"
case .winter:
return "추워요"
}
}
}
let season = Season.spring
print(season.weather()) // "따뜻해요"가 출력된다
enum, class, struct 이름 짓는 방법
enum
, class
, struct
공통으로 이름짓는 방법
enum, class, struct는 데이터타입
으로 사용할 수 있으며, 이름은 대문자로 시작하는 Camel Case로 이름을 만들고 있다.
지금까지 사용했던 String, Int 도 사실은 struct
으로 만들어진 데이터타입이라고한다.
enum Weather { // ✅ 대문자로 시작해야한다.
}
enum weather { // ❌ 소문자로 시작하면 안되다.
}
enum SeasonWeather { } // ✅ 대문자로 시작하고 Camel Case 형식으로해야한다=
enum Seasonweather { } // ❌ 대문자로 시작했지만 중간에 대문자가 없어서 읽기 불편하다.
열거형은 Swift에서 특정 주제나 종류에 따라 묶을 수 있는 값들을 그룹화하고 정의하여 데이터타입으로 사용할 수 있다.
init
class
, struct
, enum
과 같은 설계도를 기반으로 실제 메모리에 생성되는 실체다.class
, struct
, enum
은 설계도의 역할을 하고 인스턴스는 설계도를 보고 직접 만들어져서 메모리에 저장되어 있는 값이다.간단하게 설명하자면
인스턴스의 init
인스턴스를 생성할 때 상태를 초기화하여 생성해야 한다.
인스턴스를 만들때 사용되는 변수, 상수(프로퍼티)의 값을 정해주어야 한다.
init
키워드를 사용하여 모든 변수,상수(프로퍼티)을 초기화 해야 한다.enum 에서 init
enum Season: String {
case spring
case summer
case autumn
case winter
}
let season: Season = .spring
class 는 연관된 상태는 변수, 상수에 저장하고 행동은 함수를 정의한 후 그룹화하여 데이터타입으로 사용할 수 있다.
class
특징
프로퍼티
와 메소드
로 구성되어 있다.프로퍼티
라고 한다.메소드
라고 한다.프로퍼티
에는 default
값을 정해줄 수 있다.init
초기화를 제공해야 한다.init
초기화를 생략할 수 있다.Optional
인 경우 init
초기화를 생략할 수 있습.Reference Type
다.let
으로 만들어도 프로퍼티 변경된다.상속
가능class
구현방법, 초기화방법, 사용방법
// 기본 정의(구현) 방법
class 클래스이름 {
// 파라미터 선언
// 메소드 선언
// 파라미터가 있다면 init을 사용하여 초기화
}
// 사용 방법 (인스턴스로 만드는 방법)
// 클래스이름() 을 사용하면 된다.
// ()안에 클래스에서 사용하는 init에 들어가는 파라미터를 채워주면 된다.
인스턴스를 생성할 때 모든 프로퍼티를 초기화해야 하며, 이를 위해 init
키워드를 사용한다.
class
에서 init
값이 없을 수 있는 옵셔널 타입
, 초기값을 준 프로퍼티
는 예외다.init
을 여러개 만들 수 있다.convenience init
(보조 초기화) 기능을 제공한다.초기화방법
// 일반적인 init
class Person {
var name: String // 값을 저장하는 저장 프로퍼티
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
let person = Person(name: "Ryu", age: 25)
class Person {
var name: String = "이름없음"
var age: Int = 0
}
let person = Person()
// 혹은 파라미터를 받지 않는 init에서 모든 프로퍼티 값을 정해줄 수 있다.
class Person {
var name: String
var age: Int
init() {
self.name = "이름없음"
self.age = 15
}
}
init
사용class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
init(name: String) {
self.name = name
self.age = 0
}
init() {
self.name = "이름없음"
self.age = 15
}
}
convenience init
: 보조 초기화 self.init
을 사용하여 초기화를 도와준다.// 컨비니언스 이니셜라이저(convenience initializer) 사용해보기
// 파라미터에 값을 할당하지 않고 컨비니언스 이니셜라이즈를 사용해도 비슷한 효과를 낼 수 있다.
class Person {
var name: String
var age: Int // 기본값을 주지 않았다.
init(name: String, age: Int) {
self.name = name
self.age = age
}
convenience init(name: String) { // convenience init에서 name만 받은 후 아래 init에서 기본값을 정해줄 수 있다.
self.init(name: name, age: 0)
}
}
let person = Person(name: "이름만 있다.")
print(person.age) // 0
deinit
: 소멸자
class
에서만 사용 가능하다.deinit {
// 구현부
}
// 반복되는 코드
let myName = "Ryu"
let myAge = 20
let myFriendName = "감자"
let myFriendAge = 5
func introduce(name: String, age: Int) {
print("안녕하세요 \(name)입니다. 저는 \(age)살 입니다")
}
// 소개를 함수로 묶었는데 이름과 나이도 계속 중복되고 있다.
// struct이나 class로 변수,상수,함수를 관련된 내용을 모아놓을 수 있다.
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name // self는 해당 클래스의 자기 자신을 의미한다.
// Person이 갖고있는 name에 파라미터로 받은 name을 할당한니다.
self.age = age // 자신의 age 변수에 파라미터로 받은 age값을 할당한다.
}
func introduce() {
print("안녕하세요 \(name)입니다. 저는 \(age)살 입니다")
}
}
let me = Person(name: "Ryu", age: 20)
let friend = Person(name: "감자", age: 5)
me.age // me의 age 프로퍼티
me.name // me 의 name 프로퍼티
me.introduce() // me 의 introduce 함수를 호출한다.
// 출력 값 : 안녕하세요 Ryu입니다. 저는 20살 입니다
struct 는 연관된 상태는 변수, 상수에 저장하고 행동은 함수를 정의한 후 그룹화하여 데이터타입
으로 사용할 수 있다.
struct
주요 특징
프로퍼티
와 메소드
로 구성되어 있다.프로퍼티
라고 한다.메소드
라고 한다.프로퍼티
에는 default
값을 정해줄 수 있다.init
을 정의하지 않아도 모든 프로퍼티의 초기화를 자동으로 생성해주는 기능이다.Value Type
다.메소드
에서 프로퍼티
를 변경하려면 mutating
키워드를 사용해야 된다.상속
불가능let
으로 만들면 내부 프로퍼티 변경할 수 없다.var
로 만들어야 한다.struct
정의, 초기화, 사용하는 방법
// 기본 정의 방법
struct 구조체이름 {
// 프로퍼티 선언
// 함수 구현
// ⭐️ class와 다르게 init을 만들지 않아도 자동으로 만들어주어서 생략해도 된다.
}
// 사용 방법
// 구조체이름() 를 사용하면 된다.
// ()안에 구조체에서 사용하는 프로퍼티들의 내용을 채워주어야 한다.
let 상수이름 = 구조체이름()
인스턴스를 생성할 때 모든 프로퍼티를 초기화해야 하며, 이를 위해 init
키워드를 사용한다.
struct
에서 init
값이 없을 수 있는 옵셔널 타입
, 초기값을 준 프로퍼티
는 예외다.init
을 여러개 만들 수 있다.memberwise init
멤버와이즈 init을 제공한다.초기화방법
memberwise init
사용struct
에서만 제공하는 init
으로 자동으로 init을 생성해준다.
struct Person {
var name: String
var age: Int
// class와 다르게 init을 생성하지 않아도 자동으로 해준다
}
var person = Person(name: "Ryu", age: 10)
기본값을 할당한 프로퍼티가 있을 때 멤버와이즈 init는 생략하고 만들어준다.
struct Person {
var name: String = "이름없음"
var age: Int = 1
}
Person() // 기본값만 사용 가능
Person(name: "Ryu") // 이름만 변경하고 age는 기본값 사용 가능
Person(age: 15)
Person(name: "Ryu", age: 15)
init
을 직접 생성하면 memberwise init
이 사용되지 않는다.struct Person {
var name: String = "이름없음"
var age: Int = 1
init() {
print("init")
}
}
Person() // 정상동작 : Person에서 init()을 구현했기 때문에 정상동작
Person(name: "Brody") // Error : name만을 파라미터로 받는 init이 없다.
Person(age: 15) // Error : age만 파라미터로 받는 init이 없다.
Person(name: "Brody", age: 15) // Error : name, age를 파라미터로 받는 init이 없다.
struct Person {
var name: String
var age: Int
init() {
self.name = "이름 없음"
self.age = 0
}
init(name: String) {
self.name = name
self.age = 0
}
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
Person()
Person(name: "Brody")
Person(age: 15) // Error : 파라미터로 age만 전달하는 init이 없기떄문에 컴파일 오류 발생
Person(name: "Ryu", age: 15)
struct Person {
var name: String
var age: Int
func introduce() {
print("안녕하세요 \(name)입니다. 저는 \(age)살 입니다")
}
mutating func happyNewYear() {
age += 1
}
}
let me = Person(name: "Ryu", age: 20)
let friend = Person(name: "감자", age: 5)
me.age // me의 age 프로퍼티
me.name // me 의 name 프로퍼티
me.introduce() // me 의 introduce 함수를 호출합니다.
// 출력 값 : 안녕하세요 Ryu입니다. 저는 20살 입니다
// struct도 프로퍼티에 값을 준다면 초기화할 때 생략해도 된다.
struct Person {
var name: String
var age: Int = 0 // 기본값을 0을 주었다.
func introduce() {
print("안녕하세요 \(name)입니다. 저는 \(age)살 입니다")
}
}
Person(name: "홍길동", age: 20) // 초기화할 때 전달하는 age를 사용한다.
Person(name: "Ryu") // age의 기본값 0을 사용한다.
class
와 struct
가 헷갈리기 시작
class
, struct
는 프로퍼티와 메소드를 모아놓고 정의하고 사용방법도 비슷해서 헷갈린다. 심화학습
에서 메모리에 대해서 배우면서 차이점을 공부할 예정이므로 아직은 몰라도된다reference type
, value type
으로 다르다. 정도만 이해해야할것같다.Method
vs Function
class
, struct
, enum
내부에 정의된 함수를 메소드라고 부른다.class
, struct
, enum
안에 없는 전역 함수를 함수라고 부른다.// class, struct, enum등 안에 없는 전역함수 -> Function
func printName() {
print("Hi I'm Ryu")
}
struct Person {
var name: String
var age: Int = 0
// class, struct, enum 등 안에 있는 함수 -> Method
func introduce() {
print("안녕하세요 \(name)입니다. 저는 \(age)살 입니다")
}
}
let person = Person(name: "Ryu", age: 20)
Property
vs 변수,상수
프로퍼티
라고 부른다.저장 프로퍼티
, 연산 프로퍼티
, 타입 프로퍼티
등 이 있다.struct Person {
var name: String // struct 안에 있으므로 Property
var age: Int = 0
func introduce() {
print("안녕하세요 \(name)입니다. 저는 \(age)살 입니다")
}
}
let person = Person(name: "Ryu", age: 20)
// person은 struct, class 안에 없어서 상수라고 부른다.
// person안에있는 age는 Property라고 부른다.
Xcode에서 자동완성으로 나오는 경우에 확인을 할 수 있다
f : function의 약자로 함수임을 확인 할 수 있다.
M : Method의 약자로 메소드임을 확인 할 수 있다.
V : Variable의 약자로 변수/상수임을 확인 할 수 있다.
P : Property의 약자로 프로퍼티임을 확인 할 수 있다.
이런식으로 확인 할 수 있다.
class
, struct
, enum
등에서 사용되는 변수나 상수를 프로퍼티(Property)라고 한다..
프로퍼티 사용하는 방법에 따라 몇가지 유형으로 나눌 수 있다.
저장 프로퍼티(Stored Property)
프로퍼티
다.var
와 let
을 모두 사용할 수 있다.class
, struct
등에서 데이터를 저장하기 위한 변수 와 상수를 의미한다.enum
에서는 저장프로퍼티를 사용할 수 없다. (빌드 오류 발생)struct Person {
var name: String // 값을 저장하는 저장 프로퍼티
var age: Int = 0 // 값을 저장하는 초기값이 있는 저장 프로퍼티
}
연산 프로퍼티(Computed Property)
class
, struct
, enum
등 에서 사용 가능하다.var
만 사용 가능하다.let
은 사용할 수 없다.getter
와 setter
를 사용하여 동적으로 값을 계산한다.getter
는 get
키워드를 사용하여 코드블록을 구현하여 사용한다.setter
는 set
키워드를 사용하여 코드블록을 구현하여 사용한다.getter
은 필수이고 setter
는 구현하지 않아도 된다.setter
을 구현하지 않았다면 get
키워드를 생략할 수 있다.// Getter와 Setter 모두 있는 연산 프로퍼티
struct Person {
var name: String // 값을 저장하는 저장 프로퍼티
var age: Int = 0 // 값을 저장하는 초기값이 있는 저장 프로퍼티
var isAdult: Bool { // getter와 setter를 제공하는 연산 프로퍼티
get {
return age >= 20
}
set {
if newValue == true { // newValue는 할당한 새로운 값을 의미한다.
age = 20
} else {
age = 19
}
}
}
}
var person = Person(name: "Ryu", age: 100) // person 변수에 Person 구조체를 생성하여 할당한다.
// name에는 "Ryu"를 age에는 100을 할당한다.
print(person.isAdult) // age가 20보다 크므로 isAdult는 true가 된다.
person.isAdult = false // isAdult를 false로 변경하면 isAdult 연산프로퍼티의 Set
// 코드블록이 실행되어 age를 19로 변경한다.
print(person.age) // age가 19이므로 19가 출력된다.
// Setter 가 구현하지 않은 연산프로퍼티
struct Person {
var name: String // 값을 저장하는 저장 프로퍼티
var age: Int = 0 // 값을 저장하는 초기값이 있는 저장 프로퍼티
var isAdult: Bool { // getter만 제공하는 연산 프로퍼티
get {
return age >= 20
}
}
}
var person = Person(name: "Ryu", age: 100) // person 변수에 Person 구조체를 생성하여 할당한다.
// name에는 "Ryu"를 age에는 100을 할당한다.
print(person.isAdult) // age가 20보다 크므로 isAdult는 true가 된다.
person.isAdult = false // isAdult에는 Getter만 있기때문에 새로운 값을 할당할 수 없다.
// Compile Error 발생
// Setter가 구현되지 않았을 때는 get 키워드를 생략 할 수 있다.
struct Person {
var name: String // 값을 저장하는 저장 프로퍼티
var age: Int = 0 // 값을 저장하는 초기값이 있는 저장 프로퍼티
var isAdult: Bool { // get 키워드가 생략된 연산 프로퍼티 Only Get
return age >= 20
}
}
타입 프로퍼티(Type Property)
static
키워드를 사용한다.class
, struct
, enum
등 에서 사용 가능하다.타입이름.타입프로퍼티_이름
형태로 접근 가능하다.struct Person {
static var structName = "Person" // static 키워드를 사용한 타입 프로퍼티다.
// 타입 프로퍼티의 이름은 structName이고 "Person"을 할당한다.
func logStructName() {
print(Person.structName) // 내부에서는 Self로 사용 가능
}
}
var person = Person()
person.logStructName() // "Person" 출력
Person.structName = "Changed!" // Person의 타입프로퍼티 structName의 값을 "Changed!"로 변경한다.
person.logStructName() // "Changed!" 출력
print(Person.structName) // "Changed!" 출력
// enum 에서 사용하기
enum Season: String {
case spring
case summer
case autumn
case winter
static var enumName = "Season"
}
Season.enumName // "Season"
프로퍼티 옵저버(Property Observers)
저장 프로퍼티
의 값이 변경되는 것을 감시하고 있다가 코드블록을 실행할 수 있는 기능이다.class Person {
var name: String
var age: Int
var isAdult: Bool {
get {
return age >= 20
}
set {
print("Person isAdult setter 코드블록 호출됨")
if newValue == true {
age = 20
} else {
age = 19
}
}
}
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
class Child: Person { // Child class를 정의합니다. Person class를 상속받는다.
override var name: String {
willSet {
print("Child name 변경 예정 : \(newValue)")
}
didSet {
print("Child name 변경 완료 : \(oldValue)")
}
}
override var isAdult: Bool {
willSet {
print("Child isAdult 변경될 예정")
}
}
}
let child = Child(name: "Child", age: 1)
child.isAdult = false
child.name = "변경되는 이름"
저장 프로퍼티
타입뒤에 코드블록을 작성하여 만들 수 있다.저장 프로퍼티
가 사용 가능한 struct, class에서 사용 가능하다.willSet
, didSet
을 제공합니다. 둘 중 하나만 작성해도 된다.willSet
newValue
를 통해 접근하며, 이름을 정할 수 있다.willSet(이름)
형식으로 작성하면 된다.didSet
oldValue
를 통해 접근하며, 이름을 정할 수 있다.didSet(이름)
형식으로 작성하면 된다.// 기본 사용 방법
struct Person {
var name: String {
willSet {
print("Person의 name이 변경될 예정입니다. 변경될 값은 \"\(newValue)\" 입니다.")
}
didSet {
print("Person의 name이 변경되어 didSet 코드블록이 호출되었습니다.")
print("\(oldValue) -> \(name)")
}
}
var age: Int
}
var person = Person(name: "Ryu", age: 10)
person.name = "Apple"
/* 출력 값
Person의 name이 변경될 예정입니다. 변경될 값은 "Apple" 입니다.
Person의 name이 변경되어 didSet 코드블록이 호출되었습니다.
Brody -> Apple
*/
// newValue, oldValue 다른 이름으로 변경해서 사용하기
struct Person {
var name: String {
willSet(changeNewName) {
print("Person의 name이 변경될 예정입니다. 변경될 값은 \"\(changeNewName)\" 입니다.")
}
didSet(beforeName) {
print("Person의 name이 변경되어 didSet 코드블록이 호출되었습니다.")
print("\(name) -> \(beforeName)")
}
}
var age: Int
}
지연 저장 프로퍼티(Lazy Stored Property)
lazy
키워드를 사용합니다.lazy var 프로퍼티이름
형태로 사용하면 된다.var
에서만 사용 가능하다.class
, struct
등에서 사용할 수 있다.class Person {
var name: String = "A"
var age: Int = 15
lazy var height = 175.7
}
let person = Person()
// Person의 height값에 접근하지 않았기 때문에 아직 메모리에 할당되지 않은 상태
print(person.height) // height값을 사용하기 때문에 이제 메모리에 할당하여 사용함.
struct Animal {
var name: String
var age: Int
lazy var color: String = "Black"
}
var animal = Animal(name: "Dog", age: 10) // color값에 접근하지 않았기 때문에 아직 메모리에 할당되지 않은 상태
print(animal.color) // color값을 사용하기 때문에 이제 메모리에 할당하여 사용함.
class Person {
var name: String = "Default Name"
var age: Int = 15
func introduce() -> String {
return "안녕하세요. 제 이름은 \(name)이고, 나이는 \(age)살 입니다."
}
func printIndtroduce() {
print(introduce())
}
}
let person = Person()
print(person.introduce())
person.printIndtroduce()
인스턴스 메소드에서 프로퍼티 변경하기
인스턴스가 Reference Type
, Value Type
에 따라서 프로퍼티를 변경하는 방법이 나누어진다.
Reference Type
class
으로 만들어진 인스턴스
는 Reference Type
이므로, 인스턴스 메소드에서 프로퍼티 값을 직접 변경할 수 있다.class Person {
var name: String = "Default Name"
var age: Int = 15
func introduce() -> String {
return "안녕하세요. 제 이름은 \(name)이고, 나이는 \(age)살 입니다."
}
func timeToNextYear() {
age += 1 // age 프로퍼티 값에 1더한 값을 할당한다.
}
}
let person = Person()
print(person.age) // 출력 값 : 15
person.timeToNextYear() // age += 1 해서 16으로 변경
print(person.age) // 출력 값 : 16
Value Type
struct
, enum
은 value type
이므로, 인스턴스 메소드에서 프로퍼티를 직접 변경할 수 없으며 수정하려면 mutating
키워드를 사용해야 한다.// struct 메소드에서 프로퍼티 값 변경 하기
struct Person {
var name: String = "Default Name"
var age: Int = 15
func introduce() -> String {
return "안녕하세요. 제 이름은 \(name)이고, 나이는 \(age)살 입니다."
}
mutating func timeToNextYear() { // mutating 키워드를 붙여야 한다.
age += 1 // 붙이지 않으면 컴파일 오류 발생
}
}
var person = Person()
print(person.age) // 15
person.timeToNextYear() // 16으로 변경
print(person.age) // 16
// enum 메소드에서 값 변경하기
// enum은 프로퍼티가 아닌 self(자기자신)의 현재 값을 변경 할 수 있다.
enum VideoPlayerState {
case off
case playing
case complete
mutating func moveNext() { // mutating 키워드를 붙여서 값을 수정할 수 있게한다.
switch self { // mutating 키워드가 없는데 값을 변경하면 컴파일 오류 발생!
case .off:
self = .playing
case .playing:
self = .complete
case .complete:
self = .off
}
}
}
var playerState = VideoPlayerState.off
print(playerState) // 출력 값 : off
playerState.moveNext()
print(playerState) // 출력 값 : playing
playerState.moveNext()
print(playerState) // 출력 값 : completed
타입 프로퍼티
와 마찬가지로 인스턴스를 만들지 않고 호출할 수 있는 함수다.
static
키워드를 사용한다.class
, struct
, enum
등 에서 사용 가능하다.// struct, class 에서 타입 메소드 사용 방법
struct Person {
static var structName = "Person"
var name: String = "Default Name"
var age: Int = 15
func introduce() -> String {
return "안녕하세요. 제 이름은 \(name)이고, 나이는 \(age)살 입니다."
}
static func introduceType() -> String {
// name = "A" // 오류 발생! 저장 프로퍼티에는 접근할 수 없어요!
return "안녕하세요. 저는 \(structName) 타입입니다."
}
}
print(Person.introduceType()) // 출력 값 : 안녕하세요. 저는 Person 타입입니다.
// enum 에서 타입 메소드 사용 방법
enum Season {
static var enumName = "Season"
case spring
static func introduceType() -> String {
return "저는 \(enumName) 타입입니다."
}
}
print(Season.introduceType())