메서드(Methods)
특정 타입의 클래스, 구조체, 열거형과 관련된 함수
인스턴스 메서드 (Instance 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 프로퍼티를 이용해 인스턴스 자체를 참조하는데 사용 가능
- 보통 self 키워드를 사용하지 않아도 인스턴스에 등록된 메서드나 프로퍼티를 호출하면 현재 인스턴스의 메서드나 프로퍼티를 사용하는 것으로 자동으로 가정
- 예외적으로 인자 이름이 프로퍼티 이름과 같은 경우 프로퍼티에 접근하기 위해 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" 출력
인스턴스 메서드 내에서 값 타입 변경
- 구조체와 열겨형은 값 타입이기 때문에 인스턴스 메서드 내에서 값 타입의 프로퍼티를 변경할 수 없음
- 하지만 메서드에 mutating 키워드를 사용하면 메서드의 계산이 끝난 후 원본 구조체에 그 결과를 덮어 써서 값을 변경 가능
- 상수 let으로 인스턴를 선언하면 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)" 출력
let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveBy(x: 2.0, y: 3.0)
// let으로 선언해서 값 변경 시도시 에러 발생!
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)
}
}
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
타입 메서드(Type Methods)
- 특정 타입 자체에서 호출해 사용
- 타입 메서드는 메서드 키워드 func 앞에 static 혹은 class 키워드를 추가해 사용
- static 메서드: 서브클래스에서 오버라이드 할 수 없는 타입 메서드
- class 메서드: 서브클래스에서 오버라이드 할 수 있는 타입 메서드
- 타입 메서드도 인스턴스 메서드와 같이 점(.) 문법으로 호출
- 타입 메서드 안에서 self 키워드를 사용하면 타입 자신을 의미
class SomeClass {
class func someTypeMethod() {
// 타입 메서드 구현
}
}
SomeClass.someTypeMethod() // 타입 메서드 호출!
- 타입 메서드 안에서 다른 타입 메서드 사용 가능
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: 코드의 가독성과 의도를 명확하게 전달하기 위해 사용
- 메서드를 호출한 후 반환값을 사용하지 않는 경우 컴파일러 경고가 발생하지 않으므로, “이 메서드의 반환값을 사용하지 않아도 괜찮다”는 의도를 명시적으로 표현
- 사용하지 않아도 문법적으로 문제되지 않음, 개발자의 판단에 따라 사용 혹은 생략 가능
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
}
}
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" 출력
반응형
'⌨️ Language > swift' 카테고리의 다른 글
[Swift] 상속 (0) | 2024.03.22 |
---|---|
[Swift] 서브스크립트 (0) | 2024.03.22 |
[Swift] 프로퍼티 (0) | 2024.03.20 |
[Swift] 클래스와 구조체 (0) | 2024.03.19 |
[Swift] 클로저 (1) | 2024.03.18 |
댓글