Swift 3.0.1 가이드에 대응하는 정리글을 작성하였습니다!!!
Methods 정리 최신버전 링크 > http://wlaxhrl.tistory.com/44
Apple 제공 Swift 프로그래밍 가이드(2.2)의 Methods 부분을 공부하며 정리한 글입니다. 개인적인 생각도 조금 들어가있습니다.
들어가며
메서드(method)란 특정 타입에 연관된 함수(function)를 말한다. 클래스, 구조체, ENUM은 인스턴스 메서드와 타입 메서드(Objective-C에서의 클래스 메서드)를 정의할 수 있다.
Instance Methods
인스턴스 메서드는 특정 클래스, 구조체, ENUM의 인스턴스에 속하는 메서드이다. 함수와 같은 문법을 사용한다.
class Counter {
var count = 0
func increment() {
count += 1
}
func incrementBy(amount: Int) {
count += amount
}
func reset() {
count = 0
}
}
let counter = Counter() // 0
counter.increment() // 1
counter.incrementBy(5) // 6
counter.reset() // 0
<Local and External Parameter Names for Methods>
이 부분은 함수와 동일하니 그 부분을 참고하면 된다. (함수 포스팅 바로가기 > http://wlaxhrl.tistory.com/10)
간략하게 요약해보면
파라미터는 external parameter name 과 local parameter name 을 둘 다 가진다. external name 은 메서드를 호출할 때 arguments에 이름을 지정하기 위해 사용되고, local name 은 메서드 내부 구현 안에서 사용이 되는 이름이다.
디폴트로 첫 번째 파라미터는 external name이 생략되고, 두번째 파라미터부터는 자신의 local name을 external name으로 사용한다. 따라서 밖에서 호출할 때 첫 번째 파라미터는 이름 명시를 안해도 된다.
external name 이 따로 정의되어 있는 파라미터는 함수를 호출할 때 꼭 그 이름을 명시해주어야 한다. 설령 첫 번째 파라미터라도 그렇다.
두 번째 파라미터부터 : external name과 local name을 다르게 하고 싶다면 직접 external name을 지정하면 된다. external name을 없애고 싶다면 언더바(_)를 붙이면 된다.
<The self Property>
모든 인스턴스는 self 라는 프로퍼티를 가진다. 인스턴스 자신을 가리키는 참조이다. self 프로퍼티는 인스턴스 메서드내에서 현재 자신(인스턴스)을 참조할 때 쓰일 수 있다.
func increment() {
// 이런 식으로
self.count += 1
}
그러나 딱히 self를 쓰지 않더라도 인스턴스 메서드 안에서 변수/상수 이름을 사용하면 self 내의 변수/상수임을 가정해주므로 별로 쓸 일은 없다. 그러나 메서드의 파라미터 이름과 인스턴스 프로퍼티 이름이 겹칠 경우에는 써야 한다.
struct Point {
var x = 0.0, y = 0.0
func isToTheRightOfX(x: Double) -> Bool {
return self.x > x
}
}
<Modifying Value Types from Within Instance Methods>
값 타입의 프로퍼티는 인스턴스 메서드 안에서 값을 그냥은 변경할 수가 없다. 값 타입인 구조체와 ENUM의 인스턴스 메서드 안에서 프로퍼티의 값을 변경하려면 꼭 mutating 라는 키워드를 메서드 앞에 붙여야 한다.
struct Point {
var x = 0.0, y = 0.0
mutating func moveByX(deltaX: Double, y deltaY:Double) {
x += deltaX
y += deltaY
}
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveByX(2.0, y: 3.0)
let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveByX(2.0, y: 3.0) // compile error
// mutating 메서드는 let으로 선언된 인스턴스에서 사용불가
<Assigning to self Within a Mutating Method>
mutating 메서드에서 self 자체에 새로운 인스턴스를 대입하면 인스턴스 자체에 새로운 인스턴스를 할당 가능하다.
// struct의 경우
struct Point {
var x = 0.0, y = 0.0
mutating func moveByX(deltaX: Double, y deltaY:Double) {
self = Point(x: x + deltaX, y: y + deltaY)
}
}
// enum의 경우
enum TriStateSwitch {
case Off, Low, High
mutating func next() {
switch self {
case Off:
self = Low
case Low:
self = High
case High:
self = Off
}
}
}
위와 같이 인스턴스 메서드 내에서 self에 할당을 하는 것은 값타입인 구조체/ENUM만 가능하다. 클래스의 경우 mutating 메서드 자체를 정의할 수 없으며 (할 필요가 없으며) 따라서 클래스의 인스턴스 메서드 안에서 self에 할당을 하려고 하면 self는 immutable이라며 에러가 난다.
Type Methods
Objective-C에서의 클래스 메서드같이 타입 그 자체에 속하는 메서드이다.
문법은 타입 프로퍼티와 유사하다. 메서드 앞에 static 키워드를 붙여서 정의한다. 클래스의 타입 메서드의 경우 static 대신 class 키워드를 붙이면, 서브클래스에게 해당 타입 메서드의 오버라이드를 허락할 수 있다. (반대로 붙이지 않으면 오버라이드 불가)
class SomeClass {
static func someTypeMethod() {
}
class func someOverridableTypeMethod() {
}
}
class SomeChildClass: SomeClass {
override static func someTypeMethod() {
// compile error
}
override class func someOverridableTypeMethod() {
// OK
}
}
SomeClass.someTypeMethod() // 호출은 이렇게 타입에 대고 한다
타입 메서드 안에서는 자기 타입에 정의된 다른 타입 프로퍼티나 타입 메서드를 참조할 때 타입 이름을 쓰지 않아도 된다. (인스턴스 메서드 안에서도 self를 명시하지 않아도 알아서 self 내의 프로퍼티를 찾아주는 것과 동일한 원리이다. 타입 메서드 안에서의 self는 어차피 타입 그 자체이기 때문에)
struct LevelTracker {
static var highestUnlockedLevel = 1
static func unlockLevel(level: Int) {
if level > highestUnlockedLevel {
highestUnlockedLevel = level
// LevelTracker.highestUnlockedLevel 로 접근하지 않아도 된다는 것
}
}
}
'Swift 공식 가이드 > Swift 2' 카테고리의 다른 글
Inheritance (0) | 2016.04.24 |
---|---|
Subscripts (0) | 2016.04.23 |
Properties (1) | 2016.04.13 |
Classes and Structures (0) | 2016.03.27 |
Enumerations (0) | 2016.03.15 |