본문 바로가기
⌨️ Language/swift

[Swift] 메서드

by hyebin (Helia) 2024. 3. 21.

메서드(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

댓글