GGURUPiOS
Swift 공식 문서 정리 - (11) Methods 본문
메소드 (Methods)
메소드는 특정 유형과 연관된 함수임
클래스, 구조 및 열거형은 모두 지정된 유형의 인스턴스로 작업하기 위한
특정 작업 및 기능을 캡슐화하는 인스턴스 메서드를 정의 가능.
인스턴스 메소드
특정 클래스, 구조체, 열거형의 인스턴스에 속한 메소드임.
인스턴스 내의 값을 제어하거나 변경 가능.
class Counter {
var count = 0
func increment() {
count += 1
}
func increment(by amount: Int) {
count += amount
}
func reset() {
count = 0
}
}
let counter = Counter()
// 초기 count 값은 0입니다.
counter.increment()
// count 값이 1로 변경 됐습니다.
counter.increment(by: 5)
// count 값은 현재 6입니다.
counter.reset()
// count 값은 0이 됩니다.
// 함수를 한번이라도 짜 봤다면 어려운건 없어보인다.
self 프로퍼티
모든 프로퍼티는 암시적으로 인스턴스 자체를 의미하는 self 프로퍼티를 갖는다
인스턴스 메소드 안에서 self 프로퍼티를 이용해 인스턴스 자체를 참조하는데 사용 가능 함
func increment() {
self.count += 1
}
특정 메소드에서 해당 인스턴스에 등록된 메소드나 프로퍼티를 호출하면 현재 인스턴스의
메소드나 프로퍼티를 사용하는 것으로 자동으로 가정함
그러나 위 규칙이 적용 안되는 예외적인 상황이 있음
인자 이름이 프로퍼티 이름과 같은 경우임.
이럴때는 명시적으로 self 키워드를 사용해야 함 ( 모호함을 피함 )
struct Point {
var x = 0.0, y = 0.0
func isToTheRightOf(x: Double) -> Bool {
return self.x > x // self.x를 이용해 프로퍼티 x와 인자 x를 구분
}
}
let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOf(x: 1.0) {
print("This point is to the right of the line where x == 1.0")
}
// "This point is to the right of the line where x == 1.0" 출력
만약 프로퍼티와 인자 이름이 같을 때 self 키워드를 사용하지 않으면 스위프트는 자동으로 인자 이름으로 가정 함
인스턴스 메소드 내에서 값 타입 변경
구조체와 열거형은 값 타입임 → 메소드 내에서 값 타입의 프로퍼티를 변경할 수 없음
하지만 값 타입 형의 메소드에서 프로퍼티를 변경하고 싶을 때는 ?
→ mutating을 붙여 주면 가능함
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0)
print("The point is now at (\\(somePoint.x), \\(somePoint.y))")
// "The point is now at (3.0, 4.0)" 출력
하지만 var somePoint 를 let 으로 선언하면 구조체 단에서 변경이 불가능 하다는 선언이기 때문에
mutating선언과 상관없이 메소드로 값을 변경할 수 없음
Mutating 메소드 내에서 self 할당
Mutating 메소드에서 self 프로퍼티를 이용해 완전 새로운 인스턴스를 생성할 수 있음
아래 예제의 동작은 위의 예제의 동작과 일치 함
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
self = Point(x: x + deltaX, y: y + deltaY)
}
}
또한 열거형에서 Mutating 메소드를 새용해 다른 상태로 표현도 가능 하다.
enum TriStateSwitch {
case off, low, high
mutating func next() {
switch self {
case .off:
self = .low
case .low:
self = .high
case .high:
self = .off
}
}
}
var ovenLight = TriStateSwitch.low
ovenLight.next()
// ovenLight 값은 .high
ovenLight.next()
// ovenLight 값은 .off
타입 메소드
타입 메소드는 특정 타입 자체에서 호출해 사용한다.
선언은 func 앞에 static 혹은 class 키워드를 추가하면 된다.
타입 프로퍼티와 마찬가지로 static과 class의 차이는 오버라이드 여부 임 ( X / O )
호출은 점 문법으로 가능하며 인스턴스에서 호출하는 것이 아닌 타입 이름에서 호출 함
class SomeClass {
class func someTypeMethod() {
// 타입 메소드 구현
}
}
SomeClass.someTypeMethod() // 타입 메소드 호출!
~~SomeClass().someTypeMethod() // 인스턴스를 생성해서 호출 X~~
타입 메소드 안에서도 self 키워드를 사용할 수 있다.
하지만 인스턴스와 달리 인스턴스가 아닌 타입 자신을 의미함
struct LevelTracker {
static var highestUnlockedLevel = 1
var currentLevel = 1
static func unlock(_ level: Int) {
if level > highestUnlockedLevel { highestUnlockedLevel = level }
}
static func isUnlocked(_ level: Int) -> Bool {
return level <= highestUnlockedLevel
}
@discardableResult
mutating func advance(to level: Int) -> Bool {
if LevelTracker.isUnlocked(level) {
currentLevel = level
return true
} else {
return false
}
}
}
// @discardableResult -> 반환 값이 있지만, 그 값을 버릴 수 있다는 키워드
위 코드는 타입 메소드 2개, mutating 메소드 1개로
현재 레벨, 최고 레벨, 다음 레벨열기, 다음 레벨 넘어가기 기능이 구현되어있음
class Player {
var tracker = LevelTracker()
let playerName: String
func complete(level: Int) {
LevelTracker.unlock(level + 1)
tracker.advance(to: level + 1)
}
init(name: String) {
playerName = name
}
}
Player의 클래스의 complete 메소드에서 LevelTracker 인스턴스 tracker 와
타입메소드 LevelTracker.unlock을 사용해 특정 사용자의 현재 레벨을 추적하도록 구현됨
var player = Player(name: "Argyrios")
player.complete(level: 1)
print("highest unlocked level is now \\(LevelTracker.highestUnlockedLevel)")
// "highest unlocked level is now 2" 출력
레벨 1을 완료한 모습 → 레벨 2 가 열림
player = Player(name: "Beto")
if player.tracker.advance(to: 6) {
print("player is now on level 6")
} else {
print("level 6 has not yet been unlocked")
}
// "level 6 has not yet been unlocked" 출력
잠금을 해제하지 않은 레벨로 이동하려는 경우
'Swift > 공식문서 정리 ( 문법 )' 카테고리의 다른 글
Swift 공식 문서 정리 - (14) Initialization (0) | 2023.04.28 |
---|---|
Swift 공식 문서 정리 - (12) Subscripts (0) | 2023.04.28 |
Swift 공식 문서 정리 - (10) Properties (0) | 2023.04.27 |
Swift 공식 문서 정리 - (9) Structures and Classes (0) | 2023.04.27 |
Swift 공식 문서 정리 - (8) Enumerations (0) | 2023.04.27 |