* 내가 읽으려고 내 맘대로 번역한 글.
* 원문 : https://docs.swift.org/swift-book/LanguageGuide/Methods.html

 

 

 

 

Methods

Methods are functions that are associated with a particular type. Classes, structures, and enumerations can all define instance methods, which encapsulate specific tasks and functionality for working with an instance of a given type. Classes, structures, and enumerations can also define type methods, which are associated with the type itself. Type methods are similar to class methods in Objective-C.

메소드는 특정 타입과 연관된 함수다.

클래스, 구조체, 열거형은 모두 주어진 타입의 인스턴스를 사용하기 위한 인스턴스 메소드를 정의해서 특정 작업과 기능을 캡슐화 할수 있다.

클래스, 구조체, 열거형은 또한 타입 자체와 연관된 타입 메소드를 정의할수 있다.

타입 메소드는 objective-c의 클래스 메소드와 비슷하다.

 

The fact that structures and enumerations can define methods in Swift is a major difference from C and Objective-C. In Objective-C, classes are the only types that can define methods. In Swift, you can choose whether to define a class, structure, or enumeration, and still have the flexibility to define methods on the type you create.

swift에서 구조체와 열거형이 메소드를 정의할수 있다는것은 c, objective-c와의 주요한 차이점이다.

objective-c에서 클래스만이 메소드를 정의할수 있다.

swift에서는 클래스, 구조체, 열거형중 어디에 정의할지 선택할수 있고, 너가 만든 타입에 메소드를 정의하는게 유연하다.

 

Instance Methods

Instance methods are functions that belong to instances of a particular class, structure, or enumeration. They support the functionality of those instances, either by providing ways to access and modify instance properties, or by providing functionality related to the instance’s purpose. Instance methods have exactly the same syntax as functions, as described in Functions.

인스턴스 메소드는 특정 클래스, 구조체, 열거형의 인스턴스에 속한 함수다.

이 메소드들은 인스턴스들의 기능을 지원하고, 인스턴스의 속성들에 접근하거나 수정하는 방법을 제공하고, 인스턴스의 목적에 관련된 기능을 제공한다. 인스턴스 메소드는 함수의 문법과 정확히 동일하다.

 

You write an instance method within the opening and closing braces of the type it belongs to. An instance method has implicit access to all other instance methods and properties of that type. An instance method can be called only on a specific instance of the type it belongs to. It cannot be called in isolation without an existing instance.

인스턴스 메소드는 메소드가 속한 타입의 중괄호 안에 작성한다.

인스턴스 메소드는 암시적으로 같은 타입인 인스턴스의 다른 모든 메소드와 속성에 접근할수 있다.

인스턴스 메소드는 자신이 속한 타입의 특정 인스턴스에서만 호출될수 있다.

기존 인스턴스가 없으면 호출될수 없다.

 

Here’s an example that defines a simple Counter class, which can be used to count the number of times an action occurs:

여기 간단한 Counter 클래스를 정의한 샘플이 있다. 어떤 액션이 발생한 숫자 count를 사용한다.

class Counter {
	var count = 0
	func increment() {
		count += 1
	}
	func increment(by amount: Int) {
		count += amount
	}
	func reset() {
		count = 0
	}
}

 

The Counter class defines three instance methods:

Counter 클래스는 3개의 인스턴스 메소드를 정의한다.

  • increment() increments the counter by 1.
  • increment(by: Int) increments the counter by a specified integer amount.
  • reset() resets the counter to zero.

The Counter class also declares a variable property, count, to keep track of the current counter value.

You call instance methods with the same dot syntax as properties:

Counter 클래스는 또한 변수 속성 count를 선언해서, 현재 횟수 값을 추적한다.

속성과 마찬가지로 점 문법을 사용해서 인스턴스 메소드를 호출한다.

let counter = Counter()
// the initial counter value is 0
counter.increment()
// the counter's value is now 1
counter.increment(by: 5)
// the counter's value is now 6
counter.reset()
// the counter's value is now 0

 

Function parameters can have both a name (for use within the function’s body) and an argument label (for use when calling the function), as described in Function Argument Labels and Parameter Names. The same is true for method parameters, because methods are just functions that are associated with a type.

함수 매개변수는 이름과 (함수의 body안에서 사용할) 라벨(함수 호출시 사용되는)을 가질수 있다.

매소드의 매개변수도 동일하다, 왜냐면 메소드는 단지 특정 타입과 연관된 함수이기 때문이다.

 

The self Property

Every instance of a type has an implicit property called self, which is exactly equivalent to the instance itself. You use the self property to refer to the current instance within its own instance methods.

타입의 모든 인스턴스는 self 라는 암시적 속성을 가지고 있고, 이는 정확히 인스턴스 자체와 동일하다.

인스턴스 매소드 안에서 현재 인스턴스를 참조하기 위해 self 속성을 사용한다.

 

The increment() method in the example above could have been written like this:

위의 increment() 메소드는 이렇게 작성될수 있다.

func increment() {
	self.count += 1
}

 

In practice, you don’t need to write self in your code very often. If you don’t explicitly write self, Swift assumes that you are referring to a property or method of the current instance whenever you use a known property or method name within a method. This assumption is demonstrated by the use of count (rather than self.count) inside the three instance methods for C

ounter.

실제로는 너의 코드에서 자주 self를 쓸 필요가 없다.

너가 명확히 self 를 쓰지 않으면, 메소드안에서 알려진 속성이나 메소드 이름을 너가 사용할때마다 swift는 현재 인스턴스의 속성이나 메소드를 참조한다고 가정한다.

Counter의 3개 메소드 안에서 self.count 대신 count 를 사용하는걸로 이러한 가정을 보여주었다.

 

The main exception to this rule occurs when a parameter name for an instance method has the same name as a property of that instance. In this situation, the parameter name takes precedence, and it becomes necessary to refer to the property in a more qualified way. You use the self property to distinguish between the parameter name and the property name.

이러한 규칙의 중요한 예외는 인스턴스 메소드의 매개변수 이름이 인스턴스의 속성이름과 같을때 발생한다.

이런 상황에서는 매개변수 이름이 우선권을 가져서 속성을 참조하려면 보다 알맞은 방법이 필요하다.

self 속성을 사용해서 매개변수 이름과 속성 이름을 구별한다.

 

Here, self disambiguates between a method parameter called x and an instance property that is also called x:

여기, self가 x 라는 메소드 매개변수와 역시 x 라는 인스턴스 속성을 명확하게 구분해준다.

struct Point {
	var x = 0.0, y = 0.0
	func isToTheRightOf(x: Double) -> Bool {
		return self.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")
}
// Prints "This point is to the right of the line where x == 1.0"

 

Without the self prefix, Swift would assume that both uses of x referred to the method parameter called x.

self 접두사가 없으면, swift 는 둘다 x 라는 메소드 매개변수를 참조하는걸로 간주한다.

 

Modifying Value Types from Within Instance Methods

* 이석우 추가 : 주의사항 : 아래 내용은 인스턴스 메소드를 가질수 있는 구조체와 열거형에 대한 이야기다.

클래스와 달리 둘은 값타입이다. 헷갈리지 말자.

Structures and enumerations are value types. By default, the properties of a value type cannot be modified from within its instance methods.

구조체와 열거형은 값타입이다. 기본적으로 인스턴스 메소드 안에서 값타입의 속성은 수정할수 없다.

 

However, if you need to modify the properties of your structure or enumeration within a particular method, you can opt in to mutating behavior for that method. The method can then mutate (that is, change) its properties from within the method, and any changes that it makes are written back to the original structure when the method ends. The method can also assign a completely new instance to its implicit self property, and this new instance will replace the existing one when the method ends.

그럼에도 불구하고, 만약 특정 메소드안에서 구조체나 열거형의 속성의 수정이 필요하다면,

그 메소드에 대한 동작을 변경시킬수 있다. 그 메소드는 메소드안에서 자신의 속성들을 변경할수 있고,

메소드가 끝났을때 변경사항을 원본 구조체에 반영된다.

그 메소드는 또한 자신의 암시적인 self 속성에 완전히 새로운 인스턴스를 할당할수도 있고,

메소드가 끝났을때 이 새로운 인스턴스는 기존 인스턴스를 대체한다.

 

You can opt in to this behavior by placing the mutating keyword before the func keyword for that method:

메소드의 func 키워드 앞에 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))")
// Prints "The point is now at (3.0, 4.0)"

 

The Point structure above defines a mutating moveBy(x:y:) method, which moves a Point instance by a certain amount. Instead of returning a new point, this method actually modifies the point on which it is called. The mutating keyword is added to its definition to enable it to modify its properties.

위의 Point 구조체는 mutating moveBy(x:y:) 메소드를 정의해서, Point 인스턴스를 특정 양만큼 이동시킨다.

새로운 좌표를 리턴하는 대신, 이 메소드는 호출될때 실제로 좌표를 수정한다.

정의할때 추가한 mutating 키워드가 자신의 속성을 수정하도록 해준다.

 

Note that you cannot call a mutating method on a constant of structure type, because its properties cannot be changed, even if they are variable properties, as described in Stored Properties of Constant Structure Instances:

구조체 타입의 상수에는 mutating 메소드를 호출할수 없다는걸 주의해라.

왜냐면 비록 변수 속성이라도 그 속성들은 변하지 않으니까.

let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveBy(x: 2.0, y: 3.0)
// this will report an error

 

Assigning to self Within a Mutating Method

Mutating methods can assign an entirely new instance to the implicit self property. The Point example shown above could have been written in the following way instead:

Mutating 메소드는 암시적인 self 속성에 완전히 새로운 인스턴스를 할당할수 있다.

위에서 보여준 Point는 아래 방법으로 대신 작성될수 있다.

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)
	}
}

 

This version of the mutating moveBy(x:y:) method creates a new structure whose x and values are set to the target location. The end result of calling this alternative version of the method will be exactly the same as for calling the earlier version.

Mutating methods for enumerations can set the implicit self parameter to be a different case from the same enumeration:

이 버전의 mutating moveBy(x:y:) 메소드는 목표 위치로 x, y 좌표를 할당한 새로운 구조체를 만든다.

이 버젼의 메소드를 호출한 결과는 이전 버젼의 호출과 완전히 동일하다.

열거형에 대한 mutating 메소드는 암시적 self 매개변수에 다른 case 를 할당할수 있다.

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 is now equal to .high
ovenLight.next()
// ovenLight is now equal to .off

 

This example defines an enumeration for a three-state switch. The switch cycles between three different power states (off, low and high) every time its next() method is called.

이것은 3가지 상태를 가진 열거형 정의의 예이다.

next() 메소드가 호출될때마다 상태는 3가지 다른 파워 상태를 순환한다 (off, low, high)

 

Type Methods

Instance methods, as described above, are methods that you call on an instance of a particular type. You can also define methods that are called on the type itself. These kinds of methods are called type methods. You indicate type methods by writing the static keyword before the method’s func keyword. Classes can use the class keyword instead, to allow subclasses to override the superclass’s implementation of that method.

위에서 설명한 인스턴스 메소드는 특정 타입의 인스턴스에서 호출한다.

타입 자체에서 호출할수 있는 메소드를 정의할수도 있다.

이러한 메소드는 타입 메소드라고 불린다.

메소드의 func 키워드 앞에 static 키워드를 써서 타입 메소드임을 나타낸다.

클래스는 대신 class 키워드를 사용해서, 서브클래스가 슈퍼클래스의 메소드 구현을 덮어쓸수 있게 할수 있다.

 

 

NOTE

In Objective-C, you can define type-level methods only for Objective-C classes. In Swift, you can define type-level methods for all classes, structures, and enumerations. Each type method is explicitly scoped to the type it supports.

objective-c 에서는 타입 메소드는 오직 클래스에만 정의할수 있다.

swift에서는 모든 클래스, 구조체, 열거형에 타입 메소드를 정의할수 있다.

각 타입 메소드는 명시적으로 타입 자체가 지원하는 범위가 지정된다.

 

Type methods are called with dot syntax, like instance methods. However, you call type methods on the type, not on an instance of that type. Here’s how you call a type method on a class called SomeClass:

타입 메소드는 인스턴스 메소드처럼 점 문법으로 호출되고,

타입의 인스턴스가 아닌, 타입에서 타입 메소드를 호출할수 있다.

여기 SomeClass라는 클래스에서 타입 메소드를 호출하는 방법이 있다.

class SomeClass {
	class func someTypeMethod() {
		// type method implementation goes here
	}
}
SomeClass.someTypeMethod()

 

Within the body of a type method, the implicit self property refers to the type itself, rather than an instance of that type. This means that you can use self to disambiguate between type properties and type method parameters, just as you do for instance properties and instance method parameters.

타입 메소드의 body 안에서, 암시적 self 속성은 타입의 인스턴스가 아니고 타입 자체를 나타낸다.

이것은 타입 속성과 타입 메소드 매개변수를 명확하게 구분하는데 사용할수 있다.

인스턴스 속성과 인스턴스 메소드 매개변수와 마찬가지로.

 

More generally, any unqualified method and property names that you use within the body of a type method will refer to other type-level methods and properties. A type method can call another type method with the other method’s name, without needing to prefix it with the type name. Similarly, type methods on structures and enumerations can access type properties by using the type property’s name without a type name prefix.

일반적으로 타입 메소드 body 안에서 사용하는 unqualified 메소드와 속성 이름은 다른 타입 메소드와 속성을 나타낸다.

타입 메소드는 다른 타입 메소드를 호출할때 타입 이름 접두사 없이 메소드 이름 만으로도 호출할수 있다.

비슷하게 구조체와 열거형의 타입 메소드는 타입 이름 접두사 없이 타입 속성에 접근할수 있다.

 

The example below defines a structure called LevelTracker, which tracks a player’s progress through the different levels or stages of a game. It is a single-player game, but can store information for multiple players on a single device.

아래의 예제는 LevelTracker 라는 구조체를 정의해서, 게임의 단계나 레벨에 따른 사용자의 진행상황을 추적한다.

이것은 싱글 플레이어 게임이지만, 하나의 디바이스에 여러 사용자의 정보를 저장할수 있다.

 

All of the game’s levels (apart from level one) are locked when the game is first played. Every time a player finishes a level, that level is unlocked for all players on the device. The LevelTracker structure uses type properties and methods to keep track of which levels of the game have been unlocked. It also tracks the current level for an individual player.

게임이 처음 시작되면 1레벨 빼고 모든 레벨이 잠긴다.

플레이어가 하나의 레벨을 끝낼때마다, 그 레벨은 디바이스의 모든 사용자에게 열린다.

LevelTracker 구조체는 타입 속성과 메소드를 사용해서 게임의 어떤 레벨이 열렸는지 추적한다.

또한 개별 플레이어의 현재 레벨도 추적한다.

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
		}
	}
}

 

The LevelTracker structure keeps track of the highest level that any player has unlocked. This value is stored in a type property called highestUnlockedLevel.

LevelTracker 구조체 모든 플레이어가 잠금해제한 레벨중 가장 높은 레벨을 추적한다.

이 값은 highestUnlockedLevel 이라는 타입 속성에 저장된다.

 

LevelTracker also defines two type functions to work with the highestUnlockedLevel property. The first is a type function called unlock(_:), which updates the value of highestUnlockedLevel whenever a new level is unlocked. The second is a convenience type function called isUnlocked(_:), which returns true if a particular level number is already unlocked. (Note that these type methods can access the highestUnlockedLevel type property without your needing to write it as LevelTracker.highestUnlockedLevel.)

LevelTracker 는 또한 highestUnlockedLevel 속성을 다루는 2개의 타입 함수를 정의한다.

첫번째는 unlock(_:) 이라는 타입 함수인데, 새로운 레벨이 잠금해제 될때마다 highestUnlockedLevel 값을 업데이트 한다.

두번째는 isUnlocked(_:) 라는 함수인데, 특정 레벨이 이미 잠금해제 되었으면 true를 리턴한다.

(이 타입 메소드들이 highestUnloackedLevel 타입 속성에 LevelTracker.highestUnlockedLevel 이라고 쓸 필요없이

접근 가능하다는걸 잘 봐라)

 

In addition to its type property and type methods, LevelTracker tracks an individual player’s progress through the game. It uses an instance property called currentLevel to track the level that a player is currently playing.

타입 속성과 타입 메소드에 더해서, LevelTracker는 개별 플레이어의 게임 진행상황을 추적한다.

currentLevel 이라는 인스턴스 속성을 이용해서 플레이어가 현재 플레이중인 레벨을 추적한다.

 

To help manage the currentLevel property, LevelTracker defines an instance method called advance(to:). Before updating currentLevel, this method checks whether the requested new level is already unlocked. The advance(to:) method returns a Boolean value to indicate whether or not it was actually able to set currentLevel. Because it’s not necessarily a mistake for code that calls the advance(to:) method to ignore the return value, this function is marked with the @discardableResult attribute. For more information about this attribute, see Attributes.

currentLevel 속성을 관리하기 위해서, LevelTracker는 advance(to:) 라는 인스턴스 메소드를 정의한다.

currentLevel 을 업데이트 하기 전에, 이 메소드는 요청한 새로운 레벨이 이미 잠금해제 되었는지 검사한다.

advance(to:) 메소드는 Boolean 값을 리턴해서 실제로 currentLevel이 설정되었는지 여부를 나타낸다.

advance(to:) 메소드를 호출하는 코드가 리턴값을 무시하는 실수는 필요하지 않으니까.

이 함수는 @discardableResult 속성이 붙어있다.

(이석우 추가 : advance(to:) 함수를 호출하는 곳에서 리턴값을 받지 않으면, 컴파일 경고가 나는데, 이 경고를 없애주는 속성이다)

 

The LevelTracker structure is used with the Player class, shown below, to track and update the progress of an individual player:

LevelTracker 구조체는 Player 클래스와 함께 사용되고, 아래에서 보듯이, 개별 플레이어의 진행상황을 업데이트하고 추적한다.

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
	}
}

 

The Player class creates a new instance of LevelTracker to track that player’s progress. It also provides a method called complete(level:), which is called whenever a player completes a particular level. This method unlocks the next level for all players and updates the player’s progress to move them to the next level. (The Boolean return value of advance(to:) is ignored, because the level is known to have been unlocked by the call to LevelTracker.unlock(_:) on the previous line.)

Player 클래스는 LevelTracker의 새로운 인스턴스를 만들어서 플레이어의 진행상황을 추적한다.

complete(level:) 라는 메소드를 제공하는데, 플레이어가 특정 레벨을 완료할때마다 호출된다.

이 메소드는 모든 사용자에게 다음 레벨을 잠금해제하고, 플레이어의 진행상황을 다음 레벨로 업데이트시켜준다.

(advance(to:) 의 Boolean 리턴 값은 무시되었다. 왜냐면 이전 라인의 LevelTracker.unlock(_:) 에 의해서 그 레벨이 잠금해제 되었으니까)

 

You can create an instance of the Player class for a new player, and see what happens when the player completes level one:

새로운 플레이어를 위해서 Player 클래스의 인스턴스를 만들수 있고, 플레이어가 레벨하나를 끝낼을때 어떻게 되는지 볼수 있다.

var player = Player(name: "Argyrios")
player.complete(level: 1)
print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// Prints "highest unlocked level is now 2"

 

If you create a second player, whom you try to move to a level that is not yet unlocked by any player in the game, the attempt to set the player’s current level fails:

너가 두번째 플레이어를 만들고, 게임에서 아직 아무도 잠금해제 하지 않은 레베로 이동시키려고 하면,

그 플레이어의 현재 레벨을 설정하려는 시도는 실패한다.

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")
}
// Prints "level 6 has not yet been unlocked"
반응형

'iOS 초보' 카테고리의 다른 글

[swift5.1번역] 13.Inheritance  (0) 2019.08.27
[swift5.1번역] 12.Subscripts  (0) 2019.08.21
[swift5.1번역] 10.Properties  (0) 2019.08.14
[swift5.1번역] 9.Structures and Classes  (0) 2019.08.07
[swift5.1번역] 8.Enumeration  (0) 2019.08.01
Posted by 돌비
,