iOS/swift

swift - immutability (구조체 안에서)

돌맹이시터 2021. 7. 1. 16:53

 

immutable -- let과 같이 불변

mutable -- var과 같이 가변적

 

 

 

 

struct Town {

	let name: String
    var citizens: [String]
    var resources: [String : Int]
    
    init(citizens: [String], name: String, resources: [String : Int]) {
    	self.citizens = citizens
        self.name = name.uppercased()
        self.resources = resources
    }
    
    func harvestRice() {
    	resources["Rice"] = 100
        // 위의 코드는 self.resources["Rice"] = 100과 동일한 코드이다.
    }
}

 

위의 예시를 살펴보면,

struct 내부에서 저렇게 함수(메소드)를 만들었을 때

'Cannot assign through subscript: 'self' is immutable' 이라는 경고메시지가 출력된다.

 

 

struct 내부에서 "self"가 자동적으로 let으로 정의되어 있다.

위 함수의 코드블럭은

self.resources["Rice"] = 100 과 동일하고,

self이기 때문에 변할 수 없으므로 경고 메시지가 출력되는 것이다.

 

 

만약 struct 내부에서 property를 수정하고자 한다면

func 앞에 'mutating' keyword를 붙여주면 된다. (마킹한다고 표현한다)

 

 

위의 코드를

 

struct Town {

	let name: String
    var citizens: [String]
    var resources: [String : Int]
    
    init(citizens: [String], name: String, resources: [String : Int]) {
    	self.citizens = citizens
        self.name = name.uppercased()
        self.resources = resources
    }
    
    mutating func harvestRice() {
    	resources["Rice"] = 100
        // 위의 코드는 self.resources["Rice"] = 100과 동일한 코드이다.
    }
}

 

 

위와 같이 메소드 앞에 mutating을 마킹함으로써 에러가 발생하지 않게 된다.

'mutating'으로 마킹을 하게 되면 'self'가 'var'처럼 동작하고,

구조체 내부에서 구조체의 property를 자유롭게 변경할 수 있게 된다.

 

 

struct Town {

	let name: String
    var citizens: [String]
    var resources: [String : Int]
    
    init(citizens: [String], name: String, resources: [String : Int]) {
    	self.citizens = citizens
        self.name = name.uppercased()
        self.resources = resources
    }
    
    mutating func harvestRice() {
    	resources["Rice"] = 100
        // 위의 코드는 self.resources["Rice"] = 100과 동일한 코드이다.
    }
}

var myTown = Town(citizens: ["Angela", "Jack"], name : "Mytown", resources : ["Wool" : 82])

myTown.harvestRice()
print(myTown.resources)

 

 

위의 코드를 통해

harvestRice() 메소드가 정상적으로 작동함을 확인할 수 있다.

 

 

주의해야 할 점은

myTown 이 var로 선언되었기 때문에 가능한 일이며,

만약

 

let myTown과 같이 let으로 선언되었다면 mutating 마킹해서 코드를 작성했다고 하더라도,

선언 이후에 struct property를 수정할 수 없게 된다.

 

 

 

 

'iOS > swift' 카테고리의 다른 글

swift - Struct vs Class  (0) 2021.07.22
Swift - Class & Inheritance  (0) 2021.07.19
swift - Functions with Output  (0) 2021.06.29
MVC Design pattern  (0) 2021.06.28
Swift - structure (구조체)  (0) 2021.06.23