Merge changes from master into FlashMaestro

FlashMaestro authored
revision eb2b0f71149c6ff82e7eb726be510db0308dff2f
chapter18
# 18 자동 참조 계수 (Automatic Reference Counting)
> Translator : 이름 (메일주소)

Automatic Reference Counting
On This Page
Swift uses Automatic Reference Counting (ARC) to track and manage your app’s memory usage. In most cases, this means that memory management “just works” in Swift, and you do not need to think about memory management yourself. ARC automatically frees up the memory used by class instances when those instances are no longer needed.

However, in a few cases ARC requires more information about the relationships between parts of your code in order to manage memory for you. This chapter describes those situations and shows how you enable ARC to manage all of your app’s memory.

NOTE

Reference counting only applies to instances of classes. Structures and enumerations are value types, not reference types, and are not stored and passed by reference.

How ARC Works

Every time you create a new instance of a class, ARC allocates a chunk of memory to store information about that instance. This memory holds information about the type of the instance, together with the values of any stored properties associated with that instance.

Additionally, when an instance is no longer needed, ARC frees up the memory used by that instance so that the memory can be used for other purposes instead. This ensures that class instances do not take up space in memory when they are no longer needed.

However, if ARC were to deallocate an instance that was still in use, it would no longer be possible to access that instance’s properties, or call that instance’s methods. Indeed, if you tried to access the instance, your app would most likely crash.

To make sure that instances don’t disappear while they are still needed, ARC tracks how many properties, constants, and variables are currently referring to each class instance. ARC will not deallocate an instance as long as at least one active reference to that instance still exists.

To make this possible, whenever you assign a class instance to a property, constant, or variable, that property, constant, or variable makes a strong reference to the instance. The reference is called a “strong“ reference because it keeps a firm hold on that instance, and does not allow it to be deallocated for as long as that strong reference remains.

ARC in Action

Here’s an example of how Automatic Reference Counting works. This example starts with a simple class called Person, which defines a stored constant property called name:

class Person {
let name: String
init(name: String) {
self.name = name
println("\(name) is being initialized")
}
deinit {
println("\(name) is being deinitialized")
}
}
The Person class has an initializer that sets the instance’s name property and prints a message to indicate that initialization is underway. The Person class also has a deinitializer that prints a message when an instance of the class is deallocated.

The next code snippet defines three variables of type Person?, which are used to set up multiple references to a new Person instance in subsequent code snippets. Because these variables are of an optional type (Person?, not Person), they are automatically initialized with a value of nil, and do not currently reference a Person instance.

var reference1: Person?
var reference2: Person?
var reference3: Person?
You can now create a new Person instance and assign it to one of these three variables:

reference1 = Person(name: "John Appleseed")
// prints "John Appleseed is being initialized"
Note that the message "John Appleseed is being initialized" is printed at the point that you call the Person class’s initializer. This confirms that initialization has taken place.

Because the new Person instance has been assigned to the reference1 variable, there is now a strong reference from reference1 to the new Person instance. Because there is at least one strong reference, ARC makes sure that this Person is kept in memory and is not deallocated.

If you assign the same Person instance to two more variables, two more strong references to that instance are established:

reference2 = reference1
reference3 = reference1
There are now three strong references to this single Person instance.

If you break two of these strong references (including the original reference) by assigning nil to two of the variables, a single strong reference remains, and the Person instance is not deallocated:

reference1 = nil
reference2 = nil
ARC does not deallocate the Person instance until the third and final strong reference is broken, at which point it is clear that you are no longer using the Person instance:

reference3 = nil
// prints "John Appleseed is being deinitialized"
Strong Reference Cycles Between Class Instances

In the examples above, ARC is able to track the number of references to the new Person instance you create and to deallocate that Person instance when it is no longer needed.

However, it is possible to write code in which an instance of a class never gets to a point where it has zero strong references. This can happen if two class instances hold a strong reference to each other, such that each instance keeps the other alive. This is known as a strong reference cycle.

You resolve strong reference cycles by defining some of the relationships between classes as weak or unowned references instead of as strong references. This process is described in Resolving Strong Reference Cycles Between Class Instances. However, before you learn how to resolve a strong reference cycle, it is useful to understand how such a cycle is caused.

Here’s an example of how a strong reference cycle can be created by accident. This example defines two classes called Person and Apartment, which model a block of apartments and its residents:

class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { println("\(name) is being deinitialized") }
}

class Apartment {
let number: Int
init(number: Int) { self.number = number }
var tenant: Person?
deinit { println("Apartment #\(number) is being deinitialized") }
}
Every Person instance has a name property of type String and an optional apartment property that is initially nil. The apartment property is optional, because a person may not always have an apartment.

Similarly, every Apartment instance has a number property of type Int and has an optional tenant property that is initially nil. The tenant property is optional because an apartment may not always have a tenant.

Both of these classes also define a deinitializer, which prints the fact that an instance of that class is being deinitialized. This enables you to see whether instances of Person and Apartment are being deallocated as expected.

This next code snippet defines two variables of optional type called john and number73, which will be set to a specific Apartment and Person instance below. Both of these variables have an initial value of nil, by virtue of being optional:

var john: Person?
var number73: Apartment?
You can now create a specific Person instance and Apartment instance and assign these new instances to the john and number73 variables:

john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)
Here’s how the strong references look after creating and assigning these two instances. The john variable now has a strong reference to the new Person instance, and the number73 variable has a strong reference to the new Apartment instance:

image: ../Art/referenceCycle01_2x.png
You can now link the two instances together so that the person has an apartment, and the apartment has a tenant. Note that an exclamation mark (!) is used to unwrap and access the instances stored inside the john and number73 optional variables, so that the properties of those instances can be set:

john!.apartment = number73
number73!.tenant = john
Here’s how the strong references look after you link the two instances together:

image: ../Art/referenceCycle02_2x.png
Unfortunately, linking these two instances creates a strong reference cycle between them. The Person instance now has a strong reference to the Apartment instance, and the Apartment instance has a strong reference to the Person instance. Therefore, when you break the strong references held by the john and number73 variables, the reference counts do not drop to zero, and the instances are not deallocated by ARC:

john = nil
number73 = nil
Note that neither deinitializer was called when you set these two variables to nil. The strong reference cycle prevents the Person and Apartment instances from ever being deallocated, causing a memory leak in your app.

Here’s how the strong references look after you set the john and number73 variables to nil:

image: ../Art/referenceCycle03_2x.png
The strong references between the Person instance and the Apartment instance remain and cannot be broken.

Resolving Strong Reference Cycles Between Class Instances

Swift provides two ways to resolve strong reference cycles when you work with properties of class type: weak references and unowned references.

Weak and unowned references enable one instance in a reference cycle to refer to the other instance without keeping a strong hold on it. The instances can then refer to each other without creating a strong reference cycle.

Use a weak reference whenever it is valid for that reference to become nil at some point during its lifetime. Conversely, use an unowned reference when you know that the reference will never be nil once it has been set during initialization.

Weak References

A weak reference is a reference that does not keep a strong hold on the instance it refers to, and so does not stop ARC from disposing of the referenced instance. This behavior prevents the reference from becoming part of a strong reference cycle. You indicate a weak reference by placing the weak keyword before a property or variable declaration.

Use a weak reference to avoid reference cycles whenever it is possible for that reference to have “no value” at some point in its life. If the reference will always have a value, use an unowned reference instead, as described in Unowned References. In the Apartment example above, it is appropriate for an apartment to be able to have “no tenant” at some point in its lifetime, and so a weak reference is an appropriate way to break the reference cycle in this case.

NOTE

Weak references must be declared as variables, to indicate that their value can change at runtime. A weak reference cannot be declared as a constant.

Because weak references are allowed to have “no value”, you must declare every weak reference as having an optional type. Optional types are the preferred way to represent the possibility for “no value” in Swift.

Because a weak reference does not keep a strong hold on the instance it refers to, it is possible for that instance to be deallocated while the weak reference is still referring to it. Therefore, ARC automatically sets a weak reference to nil when the instance that it refers to is deallocated. You can check for the existence of a value in the weak reference, just like any other optional value, and you will never end up with a reference to an invalid instance that no longer exists.

The example below is identical to the Person and Apartment example from above, with one important difference. This time around, the Apartment type’s tenant property is declared as a weak reference:

class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { println("\(name) is being deinitialized") }
}

class Apartment {
let number: Int
init(number: Int) { self.number = number }
weak var tenant: Person?
deinit { println("Apartment #\(number) is being deinitialized") }
}
The strong references from the two variables (john and number73) and the links between the two instances are created as before:

var john: Person?
var number73: Apartment?

john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)

john!.apartment = number73
number73!.tenant = john
Here’s how the references look now that you’ve linked the two instances together:

image: ../Art/weakReference01_2x.png
The Person instance still has a strong reference to the Apartment instance, but the Apartment instance now has a weak reference to the Person instance. This means that when you break the strong reference held by the john variables, there are no more strong references to the Person instance:

image: ../Art/weakReference02_2x.png
Because there are no more strong references to the Person instance, it is deallocated:

john = nil
// prints "John Appleseed is being deinitialized"
The only remaining strong reference to the Apartment instance is from the number73 variable. If you break that strong reference, there are no more strong references to the Apartment instance:

image: ../Art/weakReference03_2x.png
Because there are no more strong references to the Apartment instance, it too is deallocated:

number73 = nil
// prints "Apartment #73 is being deinitialized"
The final two code snippets above show that the deinitializers for the Person instance and Apartment instance print their “deinitialized” messages after the john and number73 variables are set to nil. This proves that the reference cycle has been broken.

Unowned References

Like weak references, an unowned reference does not keep a strong hold on the instance it refers to. Unlike a weak reference, however, an unowned reference is assumed to always have a value. Because of this, an unowned reference is always defined as a non-optional type. You indicate an unowned reference by placing the unowned keyword before a property or variable declaration.

Because an unowned reference is non-optional, you don’t need to unwrap the unowned reference each time it is used. An unowned reference can always be accessed directly. However, ARC cannot set the reference to nil when the instance it refers to is deallocated, because variables of a non-optional type cannot be set to nil.

NOTE

If you try to access an unowned reference after the instance that it references is deallocated, you will trigger a runtime error. Use unowned references only when you are sure that the reference will always refer to an instance.

Note also that Swift guarantees your app will crash if you try to access an unowned reference after the instance it references is deallocated. You will never encounter unexpected behavior in this situation. Your app will always crash reliably, although you should, of course, prevent it from doing so.

The following example defines two classes, Customer and CreditCard, which model a bank customer and a possible credit card for that customer. These two classes each store an instance of the other class as a property. This relationship has the potential to create a strong reference cycle.

The relationship between Customer and CreditCard is slightly different from the relationship between Apartment and Person seen in the weak reference example above. In this data model, a customer may or may not have a credit card, but a credit card will always be associated with a customer. To represent this, the Customer class has an optional card property, but the CreditCard class has a non-optional customer property.

Furthermore, a new CreditCard instance can only be created by passing a number value and a customer instance to a custom CreditCard initializer. This ensures that a CreditCard instance always has a customer instance associated with it when the CreditCard instance is created.

Because a credit card will always have a customer, you define its customer property as an unowned reference, to avoid a strong reference cycle:

class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
}
deinit { println("\(name) is being deinitialized") }
}

class CreditCard {
let number: Int
unowned let customer: Customer
init(number: Int, customer: Customer) {
self.number = number
self.customer = customer
}
deinit { println("Card #\(number) is being deinitialized") }
}
This next code snippet defines an optional Customer variable called john, which will be used to store a reference to a specific customer. This variable has an initial value of nil, by virtue of being optional:

var john: Customer?
You can now create a Customer instance, and use it to initialize and assign a new CreditCard instance as that customer’s card property:

john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
Here’s how the references look, now that you’ve linked the two instances:

image: ../Art/unownedReference01_2x.png
The Customer instance now has a strong reference to the CreditCard instance, and the CreditCard instance has an unowned reference to the Customer instance.

Because of the unowned customer reference, when you break the strong reference held by the john variable, there are no more strong references to the Customer instance:

image: ../Art/unownedReference02_2x.png
Because there are no more strong references to the Customer instance, it is deallocated. After this happens, there are no more strong references to the CreditCard instance, and it too is deallocated:

john = nil
// prints "John Appleseed is being deinitialized"
// prints "Card #1234567890123456 is being deinitialized"
The final code snippet above shows that the deinitializers for the Customer instance and CreditCard instance both print their “deinitialized” messages after the john variable is set to nil.

Unowned References and Implicitly Unwrapped Optional Properties

The examples for weak and unowned references above cover two of the more common scenarios in which it is necessary to break a strong reference cycle.

The Person and Apartment example shows a situation where two properties, both of which are allowed to be nil, have the potential to cause a strong reference cycle. This scenario is best resolved with a weak reference.

The Customer and CreditCard example shows a situation where one property that is allowed to be nil and another property that cannot be nil have the potential to cause a strong reference cycle. This scenario is best resolved with an unowned reference.

However, there is a third scenario, in which both properties should always have a value, and neither property should ever be nil once initialization is complete. In this scenario, it is useful to combine an unowned property on one class with an implicitly unwrapped optional property on the other class.

This enables both properties to be accessed directly (without optional unwrapping) once initialization is complete, while still avoiding a reference cycle. This section shows you how to set up such a relationship.

The example below defines two classes, Country and City, each of which stores an instance of the other class as a property. In this data model, every country must always have a capital city, and every city must always belong to a country. To represent this, the Country class has a capitalCity property, and the City class has a country property:

class Country {
let name: String
let capitalCity: City!
init(name: String, capitalName: String) {
self.name = name
self.capitalCity = City(name: capitalName, country: self)
}
}

class City {
let name: String
unowned let country: Country
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
To set up the interdependency between the two classes, the initializer for City takes a Country instance, and stores this instance in its country property.

The initializer for City is called from within the initializer for Country. However, the initializer for Country cannot pass self to the City initializer until a new Country instance is fully initialized, as described in Two-Phase Initialization.

To cope with this requirement, you declare the capitalCity property of Country as an implicitly unwrapped optional property, indicated by the exclamation mark at the end of its type annotation (City!). This means that the capitalCity property has a default value of nil, like any other optional, but can be accessed without the need to unwrap its value as described in Implicitly Unwrapped Optionals.

Because capitalCity has a default nil value, a new Country instance is considered fully initialized as soon as the Country instance sets its name property within its initializer. This means that the Country initializer can start to reference and pass around the implicit self property as soon as the name property is set. The Country initializer can therefore pass self as one of the parameters for the City initializer when the Country initializer is setting its own capitalCity property.

All of this means that you can create the Country and City instances in a single statement, without creating a strong reference cycle, and the capitalCity property can be accessed directly, without needing to use an exclamation mark to unwrap its optional value:

var country = Country(name: "Canada", capitalName: "Ottawa")
println("\(country.name)'s capital city is called \(country.capitalCity.name)")
// prints "Canada's capital city is called Ottawa"
In the example above, the use of an implicitly unwrapped optional means that all of the two-phase class initializer requirements are satisfied. The capitalCity property can be used and accessed like a non-optional value once initialization is complete, while still avoiding a strong reference cycle.

Strong Reference Cycles for Closures

You saw above how a strong reference cycle can be created when two class instance properties hold a strong reference to each other. You also saw how to use weak and unowned references to break these strong reference cycles.

A strong reference cycle can also occur if you assign a closure to a property of a class instance, and the body of that closure captures the instance. This capture might occur because the closure’s body accesses a property of the instance, such as self.someProperty, or because the closure calls a method on the instance, such as self.someMethod(). In either case, these accesses cause the closure to “capture” self, creating a strong reference cycle.

This strong reference cycle occurs because closures, like classes, are reference types. When you assign a closure to a property, you are assigning a reference to that closure. In essence, it’s the same problem as above—two strong references are keeping each other alive. However, rather than two class instances, this time it’s a class instance and a closure that are keeping each other alive.

Swift provides an elegant solution to this problem, known as a closure capture list. However, before you learn how to break a strong reference cycle with a closure capture list, it is useful to understand how such a cycle can be caused.

The example below shows how you can create a strong reference cycle when using a closure that references self. This example defines a class called HTMLElement, which provides a simple model for an individual element within an HTML document:

class HTMLElement {

let name: String
let text: String?

@lazy var asHTML: () -> String = {
if let text = self.text {
return "<\(self.name)>\(text)"
} else {
return "<\(self.name) />"
}
}

init(name: String, text: String? = nil) {
self.name = name
self.text = text
}

deinit {
println("\(name) is being deinitialized")
}

}
The HTMLElement class defines a name property, which indicates the name of the element, such as "p" for a paragraph element, or "br" for a line break element. HTMLElement also defines an optional text property, which you can set to a string that represents the text to be rendered within that HTML element.

In addition to these two simple properties, the HTMLElement class defines a lazy property called asHTML. This property references a closure that combines name and text into an HTML string fragment. The asHTML property is of type () -> String, or “a function that takes no parameters, and returns a String value”.

By default, the asHTML property is assigned a closure that returns a string representation of an HTML tag. This tag contains the optional text value if it exists, or no text content if text does not exist. For a paragraph element, the closure would return "

some text

" or "

", depending on whether the text property equals "some text" or nil.

The asHTML property is named and used somewhat like an instance method. However, because asHTML is a closure property rather than an instance method, you can replace the default value of the asHTML property with a custom closure, if you want to change the HTML rendering for a particular HTML element.

NOTE

The asHTML property is declared as a lazy property, because it is only needed if and when the element actually needs to be rendered as a string value for some HTML output target. The fact that asHTML is a lazy property means that you can refer to self within the default closure, because the lazy property will not be accessed until after initialization has been completed and self is known to exist.

The HTMLElement class provides a single initializer, which takes a name argument and (if desired) a text argument to initialize a new element. The class also defines a deinitializer, which prints a message to show when an HTMLElement instance is deallocated.

Here’s how you use the HTMLElement class to create and print a new instance:

var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
println(paragraph!.asHTML())
// prints "

hello, world

"
NOTE

The paragraph variable above is defined as an optional HTMLElement, so that it can be set to nil below to demonstrate the presence of a strong reference cycle.

Unfortunately, the HTMLElement class, as written above, creates a strong reference cycle between an HTMLElement instance and the closure used for its default asHTML value. Here’s how the cycle looks:

image: ../Art/closureReferenceCycle01_2x.png
The instance’s asHTML property holds a strong reference to its closure. However, because the closure refers to self within its body (as a way to reference self.name and self.text), the closure captures self, which means that it holds a strong reference back to the HTMLElement instance. A strong reference cycle is created between the two. (For more information about capturing values in a closure, see Capturing Values.)

NOTE

Even though the closure refers to self multiple times, it only captures one strong reference to the HTMLElement instance.

If you set the paragraph variable to nil and break its strong reference to the HTMLElement instance, neither the HTMLElement instance nor its closure are deallocated, because of the strong reference cycle:

paragraph = nil
Note that the message in the HTMLElement deinitializer is not printed, which shows that the HTMLElement instance is not deallocated.

Resolving Strong Reference Cycles for Closures

You resolve a strong reference cycle between a closure and a class instance by defining a capture list as part of the closure’s definition. A capture list defines the rules to use when capturing one or more reference types within the closure’s body. As with strong reference cycles between two class instances, you declare each captured reference to be a weak or unowned reference rather than a strong reference. The appropriate choice of weak or unowned depends on the relationships between the different parts of your code.

NOTE

Swift requires you to write self.someProperty or self.someMethod (rather than just someProperty or someMethod) whenever you refer to a member of self within a closure. This helps you remember that it’s possible to capture self by accident.

Defining a Capture List

Each item in a capture list is a pairing of the weak or unowned keyword with a reference to a class instance (such as self or someInstance). These pairings are written within a pair of square braces, separated by commas.

Place the capture list before a closure’s parameter list and return type if they are provided:

@lazy var someClosure: (Int, String) -> String = {
[unowned self] (index: Int, stringToProcess: String) -> String in
// closure body goes here
}
If a closure does not specify a parameter list or return type because they can be inferred from context, place the capture list at the very start of the closure, followed by the in keyword:

@lazy var someClosure: () -> String = {
[unowned self] in
// closure body goes here
}
Weak and Unowned References

Define a capture in a closure as an unowned reference when the closure and the instance it captures will always refer to each other, and will always be deallocated at the same time.

Conversely, define a capture as a weak reference when the captured reference may become nil at some point in the future. Weak references are always of an optional type, and automatically become nil when the instance they reference is deallocated. This enables you to check for their existence within the closure’s body.

NOTE

If the captured reference will never become nil, it should always be captured as an unowned reference, rather than a weak reference.

An unowned reference is the appropriate capture method to use to resolve the strong reference cycle in the HTMLElement example from earlier. Here’s how you write the HTMLElement class to avoid the cycle:

class HTMLElement {

let name: String
let text: String?

@lazy var asHTML: () -> String = {
[unowned self] in
if let text = self.text {
return "<\(self.name)>\(text)"
} else {
return "<\(self.name) />"
}
}

init(name: String, text: String? = nil) {
self.name = name
self.text = text
}

deinit {
println("\(name) is being deinitialized")
}

}
This implementation of HTMLElement is identical to the previous implementation, apart from the addition of a capture list within the asHTML closure. In this case, the capture list is [unowned self], which means “capture self as an unowned reference rather than a strong reference”.

You can create and print an HTMLElement instance as before:

var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
println(paragraph!.asHTML())
// prints "

hello, world

"
Here’s how the references look with the capture list in place:

image: ../Art/closureReferenceCycle02_2x.png
This time, the capture of self by the closure is an unowned reference, and does not keep a strong hold on the HTMLElement instance it has captured. If you set the strong reference from the paragraph variable to nil, the HTMLElement instance is deallocated, as can be seen from the printing of its deinitializer message in the example below:

paragraph = nil
// prints "p is being deinitialized"

Write here...
chapter19
# 19 옵션 연쇄선택 묶임 (Optional Chaining)
> Translator : 허혁 (hyukhur@gmail.com)

선택 연쇄묶임(Optional chaining)란 nil이 될 수 있는 선택지(options)를 가진 프로퍼티(property), 메소드(method), 서브 스크립트 (subscript)에 질의하고 호출하는 프로세스를 말한다. 만약 어떤 선택지가 값을 가진다면 프로퍼티, 메소드, 서브스크립트 호출은 성공하고 선택지가 nil이면, 프로퍼티, 메소드, 서브스크립트 호출은 nil을 반환하게 된다.
여러개의 질의도 함께 엮일 수 있으며, 만약 연쇄묶임(chaining) 중간의 어떤 링크가 nil이라면 조용하게 전체 체인은 실패한다.

>Note
스위프트(Swift)의 선택 연쇄묶임가 오브젝티브씨(Objective-C)에 있는 nil에 메시지 보내기와 유사하다. 그러나, 모든 타입(any type)에서 동작하고, 성공, 실패 여부를 확인할 수 있다는 점에서 차이가 있다.

## 강제 랩핑 해제(Forced Unwrapping) 대안으로써 선택 연쇄묶임
호출하고자 하는 프로퍼티, 메소드, 서브스크립트의 선택지 값(optional value)이 nil 아닐 때 선택지 값 뒤에 물음표(?)를 두어 선택 연쇄묶임를 둘 수 있다. 이것은 선택지 값 뒤에 느낌표(!)를 두어 그 값을 강제로 랩핑 해제하는 것과 유사하다. 가장 주요한 차이점은 선택 연쇄묶임는 선택지가 nil일 때 자연스럽게 실패한다는 것이고, 강제 랩핑 해제는 선택지가 nil인 경우 런타임 에러가 발생한다.
선택 연쇄묶임가 nil 값에도 호출할 수 있다는 사실을 반영하기 위해 선택 연쇄묶임 호출 결과는 항상 선택지 값이다. 비록 질의한 프로퍼티, 메소드, 서브스크립트가 항상 선택지 값이 아닌 결과를 도출해도 그렇다. 이 선택지 반환 값을 사용해서 선택 연쇄묶임 호출이 성공했는지 ( 반환된 선택지가 값을 가지는 ) 연쇄묶임 중간의 nil 값 ( 선택지 반환값이 nil ) 때문에 실패했는지를 확인할 수 있다.
구체적으로, 선택 연쇄묶임 호출 결과는 선택지로 감싸여져 있음에도 기대한 반환값과 동일한 타입이다. 일반적으로 Int를 반환하는 프로퍼티는 선택 연쇄묶임에 따라 접근이 가능할때는 Int?를 반환할 것이다.
다은 몇몇 코드 조각은 선택 연쇄묶임가 어떻게 강제 랩핑 해제와 다르고 성공 여부 확인을 가능케 하는지 보여준다.
먼저 Person과 Residence 라는 클래스를 정의하자.
>class Person {
var residence: Residence?
}
>class Residence {
var numberOfRooms = 1
}

Residence 인스턴스(Instance)는 기본값이 1인 numberOfRooms 이라는 단 하나의 Int 프로퍼티를 가진다. Person 인스턴스는 Residence? 타입으로 residence 이라는 선택적 프로퍼티를 가진다.
만약 Person 이라는 인스턴스를 새로 만들면, 선택지가 된 효과에 따라 기본적으로 nil로 설정된다. 아래 코드에서는 john는 nil로 된 residence 프로퍼티를 가질 것이다.
let jone = Person()
만약 Person의 residence의 numberOfRooms 프로퍼티를 그 값을 강제로 랩핑 해제를 하려고 느낌표를 붙여서 접근한다면 런타임 에러(Runtime Error)를 유발시킬 것이다. 왜냐하면 해제할 residence 값 자체가 없기 때문이다.
let roomCount = john.residence.numberOfRooms
위 코드는 john.residence가 nil이 아닌 값을 성공하며 방 갯수에 적절한 숫자를 담고 있는 Int 값에 roomCount를 설정할 것이다. 그러나 이 코드는 위에 보여지는 것처럼 residence가 nil이라면 항상 런타임 에러를 유발 시킨다.
선택 연쇄묶임는 numberOfRooms 값에 접근하는데 대안법을 제공한다. 선택 연쇄묶임를 사용하기 위해 느낌표 자리에 물음표를 사용하면 된다.

>if let roomCount = john.residence?.numberOfRooms {
println("John's residence has \(roomCount) room(s).")
} else {
println("Unable to retrieve the number of rooms.")
}
// prints "Unable to retrieve the number of rooms."

이것은 스위프트(swift)가 선택적 residence 프로퍼티를 "엮고" 만약 residence가 있으면 numberOfRooms 값을 가져온다는 것을 말해준다.

numberOfRooms에 대한 접근이가 잠제적으로 실패할 수 있기 때문에 선택 연쇄묶임는 Int?이나 "선택적 Int"형 값을 반환하려고 한다. 위 예제처럼 residence가 nil인 경우는 numberOfRooms에 대한 접근이 불가능하다는 사실을 반영하기 위해서 이 선택적 Int 역시 nil이 될 것이다.
numberOfRooms가 비선택적 Int 임에도 불구하고 참인 것을 명심해라. 선택 연쇄묶임를 통해 질의한다는 것은 numberOfRooms가 Int 대신 Int?를 항상 반환할 것이라는 것을 의미한다.
john.residence에 Residence 인스턴스를 할당할 수 있는데 그러면 더이상 nil 값은 존재하지 않게 된다.
>john.residence = Residence()

john.residence는 실체 Residence 인스턴스를 이제 가지게 되었다. 만약 예전과 동일한 선택 연쇄묶임를 사용해 접근하려고 하면, 1이라는 numberOfRooms 기본값을 가지는 Int?가 반환될 것이다.

>if let roomCount = john.residence?.numberOfRooms {
println("John's residence has \(roomCount) room(s).")
} else {
println("Unable to retrieve the number of rooms.")
}
// prints "John's residence has 1 room(s)."

선택 연쇄묶임를 위한 모델(Model) 클래스(Class) 선언

프로퍼티, 메소드, 서브스크립트를 호출하는 것 같은 한단계 더 깊은 선택 연쇄묶임을 사용할 수 있다. 이는 상호관계있는 타입간의 복잡한 모델에서 서브 프로퍼티(subproperty)를 파고 들 수 있게 해주고 그 서브 프로터티에 프로퍼티와 메소드, 서브스크립트에 접근할 수 있는지 아닌지를 확인할 수 있게 해준다.
다음 코드 조각은 다단계 선택 연쇄묶임 예를 포함한 몇가지 순차적인 예제에서 사용될 4개의 모델 클래스를 정의한다. 이 클래스들은 위에 나온 Person과 Residence 모델에 Room과 Address 클래스를 추가하고 연관 프로퍼티와 메소드, 서브스크립트를 확장한다.
Person 클래스는 이전과 동일한 방법으로 정의한다.
>class Person {
var residence: Residence?
}

Residence 클래스는 이전보다 조금 복잡해졌다. 이번에는 Residence 클래스에 Room[] 타입의 빈 배열로 초기화된 rooms라는 변수 프로퍼티를 선언한다.
>‘class Residence {
var rooms = Room[]()
var numberOfRooms: Int {
return rooms.count
}
subscript(i: Int) -> Room {
return rooms[i]
}
func printNumberOfRooms() {
println("The number of rooms is \(numberOfRooms)")
}
var address: Address?
}’

이번 버전 Residence는 Room 인스턴스 배열을 저장하기 때문에, 그 numberOfRooms 프로퍼티는 저장된 프로퍼티가 아닌 계산된 프로퍼티로 구현했다. 계산된 numberOfRooms 프로퍼티는 단순히 rooms 배열에서 count 프로퍼티의 값을 반환한다.
그 rooms 배열에 접근하기 위한 바로가기로 이번 버전 Residence는 읽기만 가능한 서브 스크립트를 제공하는데 서브스크립트에게 전달받는 인덱스(index)가 적합할 것이라는 가정으로 시작해보겠다. 만약 인덱스가 적합하다면, 서브스크립트는 rooms 배열의 요청받은 인덱스의 방정보를 반환할 것이다.
또한 이번 버전 Residence는 printNumberOfRooms라는 이름의 메소드를 제공하는데 단순히 Residence에 방 갯수를 출력한다.
마지막으로 Residence에 Address?이란 타입으로 address라는 선택적 프로퍼티를 선언한다. 이를 위한 Address 클래스 타입은 밑에 정의하겠다.
rooms 배열에 사용하는 Room 클래스는 name이라는 프로퍼티 하나를 가지는 간단한 클래스인데 이는 적절한 방이름을 설정하기 위한 초기화 역할(initializer)을 한다.
>class Room {
let name: String
init(name: String) { self.name = name }
}

이 모델의 마지막 클래스는 Address이다. 이 클래스는 String? 타입의 선택적 프로퍼티를 3개 가지고 있다. 그 중 2개는 buildingName과 buildingNumber 인데 주소를 구성하는 특정 빌딩에 대한 구분을 짓기 위한 대체 수단이다. 3번째 프로퍼티인 street는 그 주소의 도로이름에 사용한다.
>class Address {
var buildingName: String?
var buildingNumber: String?
var street: String?
func buildingIdentifier() -> String? {
if buildingName {
return buildingName
} else if buildingNumber {
return buildingNumber
} else {
return nil
}
}
}

또한 Address 클래스는 String? 반환값을 가지는 buildingIdentifer 이란 이름의 메소드를 제공한다. 이 메소드는 buildingName과 buildingNumber 프로퍼티를 확인해서 만약 buildingName이 값을 가진다면 그 값을 혹은 buildingNumber이 값을 가진다면 그 값을, 둘다 값이 없다면 nil을 반환한다.

##선택 연쇄묶임를 통한 프로퍼티 호출
강제 랩핑 해제(Forced Unwrapping) 대안으로써 선택 연쇄묶임에서 봤던 것처럼 선택 연쇄묶임를 선택적 값에 대한 프로퍼티 접근에 접근할 수 있는지 만약 프로퍼티 접근이 가능한지 확인하기 위해 사용할 수 있다. 그러나 선택 연쇄묶임를 통해 프로퍼티의 값을 설정하는 것은 할 수 없다.
위에 정의한 새로운 Person 인스턴스를 사용해 클래스를 만들어 이전처럼 numberOfRooms 프로퍼티에 접근하기를 시도해본다.
>let john = Person()
if let roomCount = john.residence?.numberOfRooms {
println("John's residence has \(roomCount) room(s).")
} else {
println("Unable to retrieve the number of rooms.")
}
// prints "Unable to retrieve the number of rooms."

john.residence가 nil이기 때문에 이 선택 연쇄묶임를 예전과 동일한 방식으로 호출했지만 에러 없이 실패한다.

##선택연쇄 묶임를 통한 메소드 호출
선택 연쇄묶임를 사용해서 선택적 값을 호출하고 메소드 호출이 성공했는지 여부를 확인해볼 수 있다. 설렁 메소드가 반환값을 정의하지 않더라고 할 수 있다.
Residence 클래스에 있는 printNumberOfRooms 메소드는 numberOfRooms의 현재 값을 출력한다. 그 메소드는 다음과 같을 것이다.
>func printNumberOfRooms() {
println("The number of rooms is \(numberOfRooms)")
}

이 메소드는 반환값을 명시하지 않았다. 그러나 반환형이 없는 함수와 메소드는 Functions Without Return Values에 나와 있는 것처럼 암시적으로 Void 타입을 반환하게 된다.
만약 선택 연쇄에 있는 선택지 값에 이 메소드를 호출한다면, 메소드 반환형은 Void가 아니라 Void?이 될 것이다. 선택 연쇄를 통해 호출될 때 선택적 타입은 항상 반환 값을 가지기 때문이다. 이는 메소드가 반환값이 정의되어 있지 않더라도 printNumberOfRooms 메소드를 호출이 가능한지를 if문을 써서 확인할 수 있게 한다. printNumberOfRooms에서 암시적 반환값은 만약 메소드가 선택 연쇄를 통해 성공적으로 호출되었다면 Void와 동일할 것이고 그렇지 않다면 nil과 동일할 것이다.
>if john.residence?.printNumberOfRooms() {
println("It was possible to print the number of rooms.")
} else {
println("It was not possible to print the number of rooms.")
}
// prints "It was not possible to print the number of rooms."

##선택 연쇄를 통한 서브스크립트 호출
선택적값에 대한 서브스크립트에서 값을 가져와서 서브스크립트 호출이 성공했는지 확인하기 위해 선택 연쇄를 사용할 수 있다. 그러나 선택 연쇄를 통해 서브스크립트로 값을 설정하는 것은 할 수 없다.

>노트
선택연쇄를 통해 선택적값에 대한 서브스크립트를 접근할 때 서브스크립트 괄호(brace) 앞에 물음표를 놓아야 한다. 뒤가 아니다. 선택연쇄 물음표는 항상 선택적인 표현식의 뒤에 바로 따라나와야 한다.

아래 예는 Residence 클래스에 정의되어 있는 서브스크립트를 사용하는 john.residence 프로퍼티의 rooms 배열에 있는 첫번째 방이름을 검색하려고 하는 것이다. john.residence가 현재 nil이기 때문에 서브스크립트는 실패한다.
>if let firstRoomName = john.residence?[0].name {
println("The first room name is \(firstRoomName).")
} else {
println("Unable to retrieve the first room name.")
}
// prints "Unable to retrieve the first room name."

선택연쇄 물음표
묶임에 있는 선택지 값에 이 메소드를 호출한다면, 메소드 반환형은 Void가 아니라 Void?이 될 것이다. 선택 묶임를 통해 호출될 때 선택적 타입은 항상 반환 값을 가지기 때문이다. 이는 메소드가 반환값이 정의되어 있지 않더라도 printNumberOfRooms 메소드를 호출이 가능한지를 if문을 써서 확인할 수 있게 한다. printNumberOfRooms에서 암시적 반환값은 만약 메소드가 선택 묶임를 통해 성공적으로 호출되었다면 Void와 동일할 것이고 그렇지 않다면 nil과 동일할 것이다.
>if john.residence?.printNumberOfRooms() {
println("It was possible to print the number of rooms.")
} else {
println("It was not possible to print the number of rooms.")
}
// prints "It was not possible to print the number of rooms."

##선택 묶임를 통한 서브스크립트 호출
선택적값에 대한 서브스크립트에서 값을 가져와서 서브스크립트 호출이 성공했는지 확인하기 위해 선택 묶임를 사용할 수 있다. 그러나 선택 묶임를 통해 서브스크립트로 값을 설정하는 것은 할 수 없다.

>노트
선택연쇄를 통해 선택적값에 대한 서브스크립트를 접근할 때 서브스크립트 꺽은 괄호(bracket) 앞에 물음표를 놓아야 한다. 뒤가 아니다. 선택연쇄 물음표는 항상 선택적인 표현식의 뒤에 바로 따라나와야 한다.

아래 예는 Residence 클래스에 정의되어 있는 서브스크립트를 사용하는 john.residence 프로퍼티의 rooms 배열에 있는 첫번째 방이름을 집어오려고 하는 것이다. john.residence가 현재 nil이기 때문에 서브스크립트는 실패한다.
>if let firstRoomName = john.residence?[0].name {
println("The first room name is \(firstRoomName).")
} else {
println("Unable to retrieve the first room name.")
}
// prints "Unable to retrieve the first room name."

이 서브스크립트 호출 속에 있는 선택연쇄 물음표는 john.residence 바로 뒤, 서브스크립트 꺽은 괄호 전에 존재해야한다. 왜냐하면, john.residence가 선택연쇄를 꾀할 선택적 값이기 때문이다.
만약, john.residence에 rooms 배열에 한개 이상의 Room 인스턴스도 같이 실제 Residence를 만들어서 할당한다면 선택 묶임를 통해 rooms 배열안의 실제 아이템에 접근하기 위해서 Residence 서브스크립트를 사용할 수 있다.
>let johnsHouse = Residence()
johnsHouse.rooms += Room(name: "Living Room")
johnsHouse.rooms += Room(name: "Kitchen")
john.residence = johnsHouse
if let firstRoomName = john.residence?[0].name {
println("The first room name is \(firstRoomName).")
} else {
println("Unable to retrieve the first room name.")
}
// prints "The first room name is Living Room."

##다단계 묶임 연결하기
프로퍼티와 메소드, 서브스크립트를 사용해 모델 깊이 파고들기 위해서 선택 묶임를 여러 단계로 함께 엮을 수 있다. 그러나 다단계 선택 묶임로 반환값에 더 많은 선택적임 단계를 넣을 수는 없다.
다른 방식으로:
- 만약 집어오려고 하는 타입이 선택적이지 않으면, 선택 묶임로 인해 선택적으로 변경될 것이다.
- 만약 집어오려고 하는 타입이 이미 선택적이라면, 묶임으로 인해 더 선택적으로 변경되지는 않을 것이다.
그러므로:
- Int 타입을 선택 옵션을 통해 집어오려고 하면, 항상 Int?가 반환될 것이다. 얼마나 많은 단계의 묶임이 사용되었는지는 중요하지 않다.
- 유사하게, Int? 값을 집어오려고 하면, 항상 Int?가 반환될 것이다. 얼마나 많은 단계의 묶임이 사용되었는지는 중요하지 않다.
아래 예는 john의 residence 프로퍼티의 address 프로퍼티의 street 프로퍼티에 접근하려는 것을 보여준다. 여기에 사용되는 2개의 선택적 묶임 단계가 있는데 residence와 address로 둘은 엮여 있고 둘다 선택적 타입이다.
>if let johnsStreet = john.residence?.address?.street {
println("John's street name is \(johnsStreet).")
} else {
println("Unable to retrieve the address.")
}
// prints "Unable to retrieve the address."

john.residence의 값은 현재 적합한 Residence 인스턴스를 포함하고 있다. 그러나 john.residence.address의 값은 현재 nil이다. 이때문에, john.residence?.address?.street 호출은 실패한다.
위 예제를 잘 생각해보자. street 프로퍼티 값을 집어오고자 했다. 이 프로퍼티는 String? 이다. 그러므로 john.residence?.address?.street 의 반환값 역시 두단계 선택 묶임로 프로퍼티가 선택적 타입에 추가로 더해 적용되었음에도 불구하고 String? 이다.
만약 john.residence.address 의 값으로써 실제 Address 인스턴스를 설정하고 그 Adress의 street 프로퍼티에 실제 값을 설정한다면, 다단계 선택 묶임를 통해 그 프로퍼티 값을 접근할 수 있을 것이다.
>let johnsAddress = Address()
johnsAddress.buildingName = "The Larches"
johnsAddress.street = "Laurel Street"
john.residence!.address = johnsAddress
if let johnsStreet = john.residence?.address?.street {
println("John's street name is \(johnsStreet).")
} else {
println("Unable to retrieve the address.")
}
// prints "John's street name is Laurel Street."

john.residence.address 의 address 인스턴스에 할당하기 위해서 느낌표를 사용한 것을 잘보자. john.residence 프로퍼티는 선택적 타입을 가지기에 Residence의 address 프로퍼티에 접근하기 전에 느낌표를 사용해서 그 실제 값을 까볼 필요가 있다.

##선택적 반환값을 사용해서 메소드 묶임
이전 예제는 선택 묶임를 사용해서 선택적 타입의 프로퍼티의 값을 어떻게 집어오는지 보여주었다. 또한 선택 묶임을 사용해서 선택적 타입 값을 반환하는 메소드를 호출하고 필요하다면 그 메소드의 반환값을 연결할 수 있었다.
아래 예제는 선택 묶임을 통해 Address 클래스의 buildingIndentifer 메소드를 호출한다. 이 메소드는 String? 타입의 값을 반환한다. 이전에 설명한데로, 선택 묶임에 따라 호출된 메소드의 최종 반환값 또한 String?이 된다.
>if let buildingIdentifier = john.residence?.address?.buildingIdentifier() {
println("John's building identifier is \(buildingIdentifier).")
}
// prints "John's building identifier is The Larches."

만약 이 메소드 반환값 이상의 선택 묶임을 실행하기 원한다면, 메소드 둥근 괄호(parentheses) 다음에 선택 묶음 물음표를 두면 된다.
>if let upper = john.residence?.address?.buildingIdentifier()?.uppercaseString {
println("John's uppercase building identifier is \(upper).")
}
// prints "John's uppercase building identifier is THE LARCHES."

.
>Note
위 예제에서 둥근 괄호 다음에 선택 묶음 물음표를 놓았는데, 묶고자 하는 선택적 값이 buildingIndentifer 자체가 아니라 buildingIndentifer 메소드의 반환값이기 때문이다.

chapter21
# 21 중첩 형식 (Nested Types )
> Translator : Alice Kim (mail@jua.kim)
번역에 대한 의견이 있을 때에는 메일이나 [Chapter21 - Discussion ](https://www.penflip.com/jjuakim/swift-korean/discussions/7)에 의견을 남겨주세요

열거형(Enumerations)은 종종 특정 클래스 또는 구조체(structure)의 기능을 지원하기 위해 만들어집니다. 마찬가지로, 복잡한 형태의 맥락에서 사용하기위한 유틸리티 클래스 또는 구조체를 정의하는데 유용합니다. 이를 위해 Swift는 중첩형식을 정의 할 수있습니다. 열거형과 클래스 및 그들이 지원하는 타입의 정의를 포함한 구조체를 중첩으로 지원함[^1] 으로써 말이죠.
[^1]:
(예를 들면, 구조체 안에 클래스를 정의하고 그 클래스 안에 다시 열거형을 넣을 수있다는 얘기).

다른 형식 안에 또 다른 형식을 중첩하기 위해서는, 지원하는 유형을 둘러싸고 있는 중괄호('{','}') 안에서 정의를 작성합니다. 이러한 유형은 필요로 하는 만큼 여러 수준으로 중첩 될 수 있습니다.

## Nested Types in Action
아래의 예제에서는 블랙잭 게임에서 사용되는 게임 카드를 모델로 하는 **`BlackjackCard**`구조체를 정의하고 있습니다. **`BlakcJack**` 구조체는 내부에 **`Suit**와 **`와 `Rank**` 라는 이름의 두개의 열거형 타입을 가지고 있습니다.

블랙잭 게임에서 에이스 카드는 1또는 11의 값을 가지고 있습니다. 이러한 요소는 **`Values**`라는 구조체에 의해 표현됩니다. **`Values**` 구조체는 **`Rank**` 열거형 내부에 중첩되어 있습니다.

```c
struct BlackjackCard {
// nested Suit enumeration
enum Suit: Character {
case Spades = "♠", Hearts = "♡", Diamonds = "♢", Clubs = "♣"
}

// nested Rank enumeration
enum Rank: Int {
case Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King, Ace
struct Values {
let first: Int, second: Int?
}
var values: Values {
switch self {
case .Ace:
return Values(first: 1, second: 11)
case .Jack, .Queen, .King:
return Values(first: 10, second: nil)
default:
return Values(first: self.toRaw(), second: nil)
}
}
}

// BlackjackCard properties and methods
let rank: Rank, suit: Suit
var description: String {
var output = "suit is \(suit.toRaw()),"
output += " value is \(rank.values.first)"
if let second = rank.values.second {
output += " or \(second)"
}
return output
}
}
```

**`Suit**`열거형은 4가지 슈트(블랙잭에서 슈트란 카드에 있는 무늬를 말합니다.)[^2]들과 슈트의 그에 해당하는 **`Character**` 심볼 값을 함께 나타냅니다.

**
[^2]: 블랙잭에서 슈트란 카드에 있는 무늬를 말합니다.

`
Rank**` 열거형은 13가지 카드의 랭크와 그에 해당하는 **`Int**` 값을 나타냅니다. (**`Int**`형의 숫자 값은 Jack, Queen, King, Ace 카드에는 사용되지 않습니다.)

위의 코드를 보면 알 수 있듯이, **`Rank**` 열거형은 **`Values**`라는 추가적인 구조체를 포함하는 중첩구조의 형태를 취하고 있습니다. 이 구조는 대부분의 카드는 하나의 값을 가지지만, 에이스 카드는 두가지 값을 갖는다는 사실을 캡슐화합니다.**`Values**` 구조체는 다음과 표현하는 두가지 속성을 정의하고 있습니다.
- **`Int**` 형의 **first**
- **`Int?**` 형 또는 **optional Int** 형의 **second**

**`Rank**도 **`도 `Values**`구조체의 인스턴스를 반환하는 계산된 **values**속성을 정의합니다. 이 계산된 속성은 카드의 순위를 고려하여 그 순위에 따라 적절한 값을 가지는 새로운 **`Values**`인스턴스를 초기화 합니다. 이러한 속성은 **`Jack`, `Queen`, `King`, `Ace**` 과 같은 특별한 값을 위해 사용합니다. 숫자카드의 경우에는 지정되어 있는 **`Int**` 값을 사용합니다.

**`BlackjackCard**` 구조체는 **rank**와 **suit**라는 두개의 속성을 가지고 있고, **description**이라는 계산된 속성도 정의하고 있습니다. 이 **description** 속성은 카드의 이름과 값에 대한 설명을 빌드하기 위해 **rank**와 **suit**에 저장된 값을 사용합니다.

**`BalckjackCard**`구조체는 커스텀 이니셜라이저를 가지고 있지 않으므로, 앞 챕터의 [구조체 타입을 위한 멤버 단위의 이니셜라이저(Memberwise Initializers for Structure Types)](Intialization 챕터 쪽 링크필요)에서 설명한대로 암시적인 멤버단위 이니셜라이저(memberwise intializer)를 가지고 있습니다.

```c
let theAceOfSpades = BlackjackCard(rank: .Ace, suit: .Spades)
println("theAceOfSpades: \(theAceOfSpades.description)")
// prints "theAceOfSpades: suit is ♠, value is 1 or 11
```

**`Rank**와 **Suit**가 **`와 `Suit`가 `BlackjackCard**`안에 중첩되어 있다고 해도 그들의 타입은 문맥으로 부터 추론될 수 았가 때문에 이 인스턴스의 초기화는 자신의 맴버 이름(.Ace와 .Spades)으로 열거형 멤버를 참조할 수 있습니다. 위의 예에서는 **description**속성이 올바르게 Space Ace 카드가 1 또는 11의 값을 가지고 있는지 확인합니다.

## 중첩 형식을 참조하기 (Referring to Nested Types)
자신이 정의된 문맥 외부에서 중첩형식을 사용하려면, 자기를 포함하고 있는(중첩하고 있는)형식의 이름을 그 이름앞에 붙입니다.

```c
let heartsSymbol = BlackjackCard.Suit.Hearts.toRaw()
// heartsSymbol is "♡"
```

위의 예를 보면, 그들의 이름은 자연스럽게 그들이 정의된 문맥에 의해 규정되기 때문에 **`Suit`, `Rank`, `Values**`의 이름이 의도적으로 짧게 할 수 있습니다.
chapter5
# 05 문자열과 문자 (Strings and Characters)
> Translator : 이름 (메일주소)

Write here...
해탈 (kimqqyun@gmail.com)

# 문자열과 문자 (Strings and Characters)

문자열은 `"hello, world"` 또는 `"albatross"` 와 같은 문자의 컬렉션입니다. Swift 문자열을 차례로 문자 타입을 컬렉션 값으로 표시됩니다.

Swift 문자열 및 문자 타입은 텍스트로 작업하는 유형에서 유니코드 호환방법을 빠르게 제공합니다. 문자 생성 및 조작을 위한 구문은 C 문자열과 유사한 구문을 사용하여 가볍게 읽을 수 있습니다. 문자열 연결은 `+` 연산자와 함께 두 문자열을 추가하는 것만 만큼 간단하고 문자열의 가변성은 Swift의 다른 값과 상수나 변수 그리고 다른 값들의 선택에 의해 관리됩니다.

Swift의 문자열 유형은 빠르고 현대적인 구현에도 불구하고 문법이 단순합니다. 모든 문자열 인코딩이 독립적인 유니코드 문자로 구성, 다양한 유니코드 표현에 액세스 하기위한 지원을 제공합니다.

문자열 삽입 과정에서 상수, 변수, 리터럴 및 긴 문자열을 삽입 할수 있습니다. 이것은 사용자 정의 문자열값 만들어서 보여주거나 저장하기를 쉽게 할 수 있습니다.


> NOTE
>
> Swift의 문자열 타입은 Foundation의 NSString 클래스에 연결됩니다. 당신은 Cocoa 또는 Cocoa Touch의 Foundation 프레임워크로 작업하는 경우 NSString의 API를 이용하여 문자열 값 호춣이 만드는 것이 가능하며 또한 이 장에서 설명한 문자열 기능도 사용가능합니다. 또한 NSString의 API 인스턴스를 필요로 하는 문자열 값도 사용가능합니다.
>
>Foundation 과 Cocoa 에 대한 자세한 정보는 _Using Swift With Cocoa and Objective-C_ 를 참조하십시오 // 이탤릭체

## 문자열 리터럴

코드 내에서 미리 정의된 문자열값인 리터럴등을 포함할 수 있습니다. 문자열 리터럴이란 큰 따옴표로 둘라싸인 텍스트 문자의 고정된 순서입니다.

문자열 리터럴은 상수나 변수의 초기 값을 제공하는것에 사용될 수 있습니다.
```
let someString = "Some string literal value"
```

Swift는 초기화된 문자열 리터럴 값으로 `someString` 상수에 대한 문자열의 형식을 유추합니다.

문자열 리터럴은 다음과 같은 특수 문자를 포함 할 수 있습니다.

- 이스케이프 특별 문자 `\0` (null 문자), `\\` (백슬래시), `\t` (수평 탭), `¶
` (줄 바꿈), `\r` (캐리지 리턴), `\"` (큰 따옴표), `\'` (작은 따옴표)
- 1바이트 유니코드 스칼라는 `\xnn` 이며 `nn`은 두개의 16진수 숫자입니다.
- 2바이트 유니코드 스칼라는 `\unnnn` 이며 `nnnn`은 4개의 16진수 숫자입니다.
- 4바이트 유니코드 스칼라는 `\Unnnnnnnn` 이며 `nnnnnnnn`은 8개의 16진수 숫자입니다.

아래의 코드는 여러 종류의 특수문자의 예를 나타냅니다.
`wiseWords` 상수는 두개의 이스케이프 문자가 포함되어 있습니다. `dollarSign` 과 `blackHeart` 및 `sparklingHeart` tkdtnsms 세가지 유니코드 스칼라 문자 형식을 보여줍니다.

```
let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
// "Imagination is more important than knowledge" - Einstein
let dollarSign = "\x24" // $, Unicode scalar U+0024
let blackHeart = "\u2665" // ♥, Unicode scalar U+2665
let sparklingHeart = "\U0001F496" // 💖, Unicode scalar U+1F496
```

## 빈 문자의 초기화 (Initializing an Empty String)

긴 문자 열을 만들기 위한 포인트를 위해 빈 문자열 값을 만들려면 빈 문자열 리터럴을 변수에 할당하거나 초기화 문법을 사용하여 새 문자열 인스턴스를 초기화합니다.

```
var emptyString = "" // 빈 문자열 리터럴
var anotherEmptyString = String() // 초기화 문법
// 두 문자열 모두 비어있으며 서로 똑같다.

```

`isEmpty`의 불리언 속성을 체크하여 문자열 값이 비어있는지 여부를 확인할 수 있습니다.
```
if emptyString.isEmpty {
println("여기엔 아무것도 보이지 않습니다.")
}
// prints 여긴 아무것도 보이지 않습니다."
```

## 문자열 가변성

특정 문자열을 변수에 할당하여(수정될 수 있는 경우) 수정(또는 변경)할 수 있는지를 나타내거나 상수(수정될 수 없는 경우)를 말합니다.
```
var variableString = "Horse"
variableString += " and carriage"
// variableString 은 "Horse and carriage" 입니다.

let constantString = "Highlander"
constantString += " and another Highlander"
// 컴파일 에러 - 상수 문자열은 변경될 수 없습니다.
```

> NOTE
> 이 방법은 Objective-C 또는 Cocoa에서 다른 방법으로 접근하는데 문자열이 변경될수 있는지 여부를 나타내기 위해 두 개의 클래스 (NSString 또는 NSMutableString) 사이에서 선택할 수 있습니다.

## 문자열 값 타입 (Strings Are Value Types)

Swift의 문자열 타입은 값 타입닙니다. 새 문자열 값을 만드는 경우에 상수 또는 변수에 할당되면 그 문자열 값이 함수나 메소드에 전달 될때 복사 됩니다. 각각의 경우에 기존의 문자열 값의 새 복사본이 전달되거나 복사되며 이는 원래의 버전이 아닙니다. 값 타입은 Structurs and Enumerations Are Value Types를 참조하십시오. // 링크

>NOTE
>
>이 동작은 Cocoa에 있는 NSString 과는 다릅니다. Cocoa에 있는 NSString 인스턴스를 생성할때와 함수나 메소드에 전달하거나 변수에 할당 및 전달될때 동일한 단일 NSString에 대한 참조를 할당합니다. 특별히 요청하지 않는 한 문자열에 대해 어떠한 복사는 수행되지 않습니다.

Swift의 문자열 기본 복사 동작(copy-by-default)은 문자열 값이 함수나 메소드에의해 수행될때 어디에서 오는지 상관 없이 정확한 문자열 값을 소유하고 깨끗한지 확인합니다.스스로 수정하지 않는한 전달된 문자열이 수정되지 않는다는것을 보장합니다.

내부적으로 Swift의 컴파일러는 실제 복사가 반드시 필요한 경우에만 발생하도록 최적화하고있습니다. 이 뜻은 문자열로 작업할때 항상 좋은 성능을 의미합니다.

## 문자와 작업하기 (Working with Charaters)

Swift의 문자열 타입은 지정된 순서로 문자 값의 컬렉션을 타나냅니다. 각 문자의 값은 하나의 유니코드 문자를 나타냅니다. 각 문자에 대해 for-in 루프의 문자 반복을 사용하여 각각의 문자의 값에 접근할 수 있습니다.

```
for character in "Dog! " // 개 특수문자 {
println(character)
}
// D
// o
// g
// !
// 개 특수문자
```

for-in 루프에 대해서는 For Loops 를 참조하십시오 // 링크

그 대신에 문자 형식 주석을 제공하여 단일 문자열 리터럴에서 톡립(stand-alone) 문자 상수나 변수를 만듭니다.

```
let yenSign: Character = "¥"
```

## 문자 세기 (Counting Characters)
문자열의 문자의 수를 검색하려면 전역 함수인 countElements를 호출하여 함수의 유일한 매개변수인 문자열을 전달합니다.

```
let unusualMenagerie = "Koala , Snail , Penguin , Dromedary"
println("unusualMenagerie has \(countElements(unusualMenagerie)) characters")
// prints "unusualMenagerie has 40 characters"
```

> NOTE
>
> 다른 유니코드 문자와 같은 유니코드 문자의 다른 표현은 메모리의 저장된 다른 양을 필요로 할 수 있습니다. 이때문에 Swift의 문자는 각 문자의 표현에서 동일한 양의 메모리를 차지하지 않습니다. 결과에 따라 문자열의 길이는 차례로 그 문자의 각각 반복하지 않고는 계산될 수 없다. 당신이 특히 긴 문 자열 값으로 작업하는 경우 `CountElements` 기능이 해당 문자열에 대한 정확한 글자수를 계산하기 위해 문자열에서 문자 세기를 반복해야한다는 것을 인식해야합니다.
>
>또한 `countElements`에 의해 반환된 문자수는 항상 같은 문자가 포함되어있는 `NSSString` 의 길이 속성과 동일하지 않습니다. 길이는 `NSString`을 기초로한 문자열 UTF-16 표현내의 16비트 유닛 숫자에 기반하고 문자열에서 유니코드 문자의 수에 기반하지는 않습니다.
이 사실을 반영하기 위해 길이 속성은 Swift가 `NSString` 문자열 값에 접근할때 `utf16count` 라고 합니다.

## 문자열 및 문자 합치기

문자열 및 문자를 덧셈 연산자(`+`)와 함께 추가하여 새로운 문자열(또는 연결된) 값을 만들 수 있습니다.

```
let string1 = "hello"
let string2 = "there"
let character1: Character = "!"
let character2: Character = "?"

let stringPlusCharacter = string1 + character1 // equals "hello!"
let stringPlusString = string1 + string2 // equals "hello there"
let characterPlusString = character1 + string1 // equals "!hello"
let characterPlusCharacter = character1 + character2 // equals "!?"
```
또한 덧셈할당연산자(+=)로 기존의 문자열 변수에 문자열이나 문자 값을 추가할 수 있습니다.
```
var instruction = "look over"
instruction += sting2
// instriction 은 "look over there" 와 같습니다.

var welcome = "good mornig"
welcome += character1
// welcome 은 "good morning!" 과 같습니다.
```

> NOTE
>
> 문자 값은 하나의 문자만을 포함해야만 하기 떄문에 기존의 문자변수에 문자열이나 문자를 추가 할 수 없습니다.

## 문자열 삽입

문자열 삽입은 상수, 변수, 리터럴 그리고 표현식의 혼합을 이용, 문자열 안에 문자 값을 포함하여 새로운 문자열 값을 만드는 방법입니다. 문자열 리터럴에 삽입된 각 항목은 백슬래시가 앞에 한 쌍의 괄호로 싸여있습니다.
```
let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
// message is "3 times 2.5 is 7.5"
```
위의 예에서 `multiplier`의 값은 `\(multiplier)` 문자열 리터럴로 삽입됩니다. 이 플레이스 홀더는 실제 문자열 삽입이 평가(evaluate)될때 `multiplier`의 실제 값으로 치환됩니다.

`multiplier`의 값은 큰 문자열 표현식의 후의 일부입니다. 이 표현식은 `Double(mutiplier) * 2.5` 의 값을 계산하고 문자열로 결과 (`7.5`)를 삽입합니다. 이 경우에 문자열 리터럴 내부에 포함된 경우 표현은 `\(Double(multiplier) * 2.5)`로 기록됩니다.


> NOTE
>
> 문자열에 삽입된 괄호안에 쓰는 표현으로 이스케이프 큰 따옴표 (`"`) 또는 백 슬래시(`\`)와 캐리지 리턴 및 줄바꿈을 포함할 수 없습니다.

## 문자열 비교
Swift는 문자열 값을 비교하는 세가지 방법을 제공합니다 : 문자열 같음, 접두사 같음, 접미사 같음 // 디스커션에 올림

### String Equality
두개의 문자열 값이 동일한 순서로 포함되어 있는 경우 두개의 문자열 값이 동일한 것으로 간주됩니다.

```
let quotation = "We're a lot alike, you and I."
let sameQuotation = "We're a lot alike, you and I."
if quotation == sameQuotation {
pinrtln("These two strings are considered equal")
}
// prints "These two strings are considered equal"
```


### Prefix and Suffix Equality

문자열이 특정 문자열의 접두사 또는 접미사가 있는지 여부를 확인하여 문자열의 hasPrefix 및 hasSuffix 메서드를 호출, String 타입의 단일 인수인 부울값을 각각 반환합니다. 두 가지 방법은 기본 문자열과 접두사나 문자열 사이에 문자별 비교를 수행합니다. 두 가지 방법은 기본 문자열과 접두사나 접미사 문자열 사이의 문자별 비교를 수행합니다.


아래의 예는 _셰익스피어의 로미오와 줄리엣_ 의 처음 두 액트인 장면의 위치를 나타내는 문자열의 배열를 고려하였습니다.

```
let romeoAndJuliet = [
"Act 1 Scene 1: Verona, A public place",
"Act 1 Scene 2: Capulet's mansion",
"Act 1 Scene 3: A room in Capulet's mansion",
"Act 1 Scene 4: A street outside Capulet's mansion",
"Act 1 Scene 5: The Great Hall in Capulet's mansion",
"Act 2 Scene 1: Outside Capulet's mansion",
"Act 2 Scene 2: Capulet's orchard",
"Act 2 Scene 3: Outside Friar Lawrence's cell",
"Act 2 Scene 4: A street in Verona",
"Act 2 Scene 5: Capulet's mansion",
"Act 2 Scene 6: Friar Lawrence's cell"
]
```
Act 1의 장면의 수를 `romeoAndJuliet` 배열에 `hasPrefix`를 사용하여 계산할수 있습니다.


```
var act1SceneCount = 0
for scene in romeoAndJuliet {
if scene.hasPrefix("Act 1 ") {
++act1SceneCount
}
}
println("There are \(act1SceneCount) scenes in Act 1")
// prints "There are 5 scenes in Act 1"
```

마찬가지로 `hasSiffix` 메소드를 사용하여 Capulet's mansion and Friar Lawrence's cell의 장면의 수를 계산합니다

```
var mansionCount = 0
var cellCount = 0
for scene in romeoAndJuliet {
if scene.hasSuffix("Capulet's mansion") {
++mansionCount
} else if scene.hasSuffix("Friar Lawrence's cell") {
++cellCount
}
}
println("\(mansionCount) mansion scenes; \(cellCount) cell scenes")
// prints "6 mansion scenes; 2 cell scenes"
```

## 대문자 와 소문자 문자열
uppercaseString 과 lowercaseString 속성을 가진 문자열에 대문자와 소문자 버전에 접근할 수 있습니다.

```
let normal = "Could you help me, please?"
let shouty = normal.uppercaseString
// shouty is equal to "COULD YOU HELP ME, PLEASE?"
let whispered = normal.lowercaseString
// whispered is equal to "could you help me, please?"
```

## 유니코드
유니코드는 국제 표준 인코딩 및 텍스트를 나타내는것입니다. 유니코드는 표준화된 형태로 거의 모든 문자를 표시하고 텍스트 파일 또는 웹페이지와 같은 외부 소스로 부터 해당문자를 읽고 쓸 수 있습니다.

Swift의 문자열 및 문자 유형은 유니코드를 완벽하게 준수합니다. 아래에 설명으로 그들은 서로 다른 유니코드 인코딩의 숫자를 지원합니다.

### 유니코드 용어

유니코드의 모든 문자는 하나 이상의 유티코드 스칼라로 표현될 수 있습니다. 유니코드 스칼라는 문자 또는 수정에 대한 고유한 21bit(그리고 이름) 입니다, 이러한 `U+0061`나 `LOWERCASE LATINLETTER A("a")` 과 같이 `U+1F425`와 `FRONT-FACING BABY CHICK("오리?")` 같은것 말입니다. // 오리로 보이는 특수문자

유니코드 문자열이 텍스트 파일이나 다른 저장소에 기록될때 이러한 유니코드 스칼라는 여러 유니코드 저으이중 하나의 형식으로 인코딩됩니다. 각형식은 코드 단위로 알려진 작은 덩어리의 문자열을 인코딩합니다. 이들은 UTF-8 (8 비트 코드 단위로 문자열을 인코딩) 형식과 UTF-16 (16 비트 코드 단위로 문자열을 인코딩) 형식을 포함하고 있습니다.

### 문자열의 유니코드 표현

Swift는 문자열의 유니코드 표현에 접근할 수 있는 여러가지 방법을 제공합니다.

유니코드 문자로 개별 문자 값에 접근을 `for-in` 구문으로 반복할 수 있습니다. 이 과정은 문자와 작업하기에 설명되어있습니다.

또한 유니코드 호환 표현중 하나의 문자열 값에 접근:

- UTF-8 코드단위의 컬렉션(문자열의 `UTF-8` 속성에 접근)
- UTF-16 코드단위의 컬렉션 (문자열의 `UTF-16` 속성에 접근)
- UTF-21비트 유니코드 스칼라 값의 컬렉션 (문자열의 `unicodeScalars` 속성에 접근)

아래의 각 예제에서는 D,O,G,! 및 (DOG FACE) 문자로 구성되어 있으며 문자열은 다른 표현을 보여줍니다. (DOG FACE 또는 유니코드 스칼라 U+1F436)

```
let dogString = "Dog!" // 특수문자
```

### UTF-8

문자열의 UTF-8 속성을 반복하여 문자열의 `UTF-8` 표현에 접근할 수 있습니다.
UTF8View 타임의 속성은 부호 없는 8 비트(UInt8) 값의 모음이며 문자열의 UTF-8 의 각 바이트 문자열 표현입니다.:

```
for codeUnit in dogString.utf8 {
print("\(codeUnit) ")
}
print("¶
")
// 68 111 103 33 240 159 144 182
```

위의 예에서 첫 번째 네개의 십진수 `codeUnit` 값(`68`,`111`,`103`,`33`)은 그 문자 UTF-8로 표현과 동일한 D,o,g 그리고 !를 나타내며 이것들은 ASCII의 표현과 동일합니다. 마지막 네개의 codeUnit의 값(`240`,`159`,`144`,`182`)은 `DOG FACE`의 4바이트 UTF-8 표현입니다.

### UTF-16

UTF-16 속성에 반복하여 UTF-16 표현에 접근할수 있습니다. `UTF8View` 타입의 속성은 부호 없는 16 비트(`UInt16`)값의 모음이며 문자열의 UTF-16의 각 바이트 문자열 표현입니다.:

```
for codeUnit in dogString.utf16 {
print("\(codeUnit) ")
}
print("¶
")
// 68 111 103 33 55357 56374

```

다시 처음 4가지 `codeUnit`의 값(`68`,`111`, `103`, `33`)은 UTF-16 코드 단위의 값은 UTF-8의 문자열 표현과 같은 값을 가지며 D,o,g 그리고 !의 문자를 표현합니다.

다섯 번째와 여섯 번째 `codeUnit`의 값(`55357` 과 `56374`)는 `DOG FACE` 문자를 UTF-16을 써로게이트 페어로 표현한것이다. 이 값은 `U+D83D`(십진수 값 `55357`)의 lead 써로게이트 값과 `U+DC36`(십진수 값 `56374`)의 trail 써로게이트 값입니다.




chapter8
# 08 함수 (Functions)
> Translator : Quartet( ungsik.yun@gmail.com )

함수는 특정 일을 수행하는 자기 완결성(Self-contained)을 가진 코드들의 집합입니다. 함수의 이름을 지으면서 이 함수가 무엇을 하는지 식별하게 할 수 있습니다. 그리고 그 이름으로 함수를 "호출(Call)"하여 필요할때 함수의 일을 수행하게 만들 수 있습니다.
스위프트(Swift)의 함수 문법은 파라메터가 없는 C스타일의 함수에서부터 지역 파라메터와 파라메터 이름 각각에 대한 외부 파라메터를 가지고 있는 복잡한 오브젝티브-C 스타일의 함수까지 전부 표현할 수 있습니다. 파라메터는 기본 값을 가질수 있어 단순한 함수 호출에 쓰일수 있습니다. 또한 In-out 파라메터로서 변수를 넘겨 변수가 함수의 실행후에 파라메터가 변경되게 할 수도 있습니다.
파라메터 타입과 반환(Return) 타입으로 이루어진 모든 스위프트의 함수들은 타입을 가집니다. 스위프트에 있는 다른 타입들과 마찬가지로, 함수의 타입들을 사용할 수 있습니다. 즉 함수를 다른 함수에 파라메터로서 넘겨주거나 함수를 다른 함수에서 반환받을 수 있습니다. 함수들은 유용한 기능 캡슐화를 위해 중첩된 함수안의 범위 내에서 쓰여질수도 있습니다.

## 함수 정의와 호출
함수를 정의할때 함수의 입력(파라메터)을 하나 이상의 이름이 있고 타입이 정해진 값으로 할 수 있습니다. 또한 값의 타입은 함수의 실행이 끝났을때 함수가 되돌려줄 수 있습니다 (반환 타입).
모든 함수는 함수명을 가지고 있으며, 함수명은 함수가 하는일을 설명해줍니다. 함수를 사용하기위해서 함수를 함수의 이름을 사용하여 "호출"하고 함수의 파라메터 타입들과 일치하는 입력 값들(아규먼트Arguments)을 넘겨줍니다. 함수의 입력값은 함수의 파라메터리스트와 언제나 일치해야합니다.
아래의 함수 예제 이름은 `greetingForPerson`입니다. 함수가 행하는 일이 바로 그것(사람에게 환영인사Greeting for person)이기 때문입니다. 입력으로 사람의 이름을 받아서 그 사람에 대한 환영 인사를 반환합니다. 이를 달성하기 위해 파라메터를 하나 정의하고 - `personName`이라는 `String` 값 - 반환 타입을 `String`으로 합니다. 그렇게 그하여 사람에 대한 환영 인사를 포함하는 것입니다.

```
func sayHello(personName: String) -> String {
let greeting = "Hello, " + personName + "!"
return greeting
}
```
이 모든 정보들은 `func` 키워드 접두어를 쓰는 함수의 정의안에 포함이 되게도비니다. 함수의 반환 타입을 표시하기위해 함수 이름의 오른쪽에 화살표(하이픈과 우측 꺽괄호) `->`를 사용하여 화살표 오른쪽에 와 반환할 타입을 표시합니다.
함수 정의는 함수가 무엇을 하는지, 무엇을 파라메터로 받는지 완료되었을때 무엇을 반환하는지 설명합니다. 함수 정의는 함수가 코드안에서 호출될때 명확하고 애매함이 없는 방법으로 사용될수 있게합니다:

```
println(sayHello("Anna"))
// prints "Hello, Anna!"
println(sayHello("Brian"))
// prints "Hello, Brian!"
```
`sayHello` 함수를 괄호안에 `String` 타입의 인수를 넣어서 호출합니다. 예를들면 `sayHello("Anna")` 처럼 말이죠. `sayHello`가 `String`타입을 반환하기에 `sayHello`함수는 `println`로 싸여서 호출될 수 있습니다. 이렇게 함으로서 `println`함수가 `sayHello`함수의 반환값을 위에 보이는 것처럼 출력할 수 있습니다.
`sayHello`함수의 몸체는 `greeting`이라는 새 `String` 상수를 선언하는 것으로 시작합니다. 그리고 `greeting`을 `personName`에 대한 단순한 환영인사 메시지로 설정합니다. 이 환영 인사는 `return`키워드를 통해 함수의 밖으로 되돌려지게 됩니다. `return greeting`이 실행 되면 함수의 실행은 끝나게되고, `greeting`의 현재 값을 돌려주게됩니다.
`sayHello` 함수를 다른 입력값으로 여러번 호출할 수 있습니다. 위의 예제는 입력값이 "Anna", "Brian" 일때를 각각 보여주고 있습니다. 함수는 사람(입력값)에 맞게끔 환영인사를 각각의 경우에 맞추어 돌려줍니다.
함수 몸체를 단순화하기 위해서는, 메시지의 생성과 반환을 한줄로 합치면 됩니다:
```
func sayHelloAgain(personName: String) -> String {
return "Helloagain, " + personName + "!"
}
println(sayHelloAgain("Anna"))
// prints "Helloagain, Anna! "
```
## 함수 파라메터와 반환값
스위프트에서 함수 파라메터와 반환값은 극도로 유연합니다. 이름없는 파라메터를 사용하는 단순한 기능성 함수에서부터 명시적 파라메터 이름(expressive parameter names)과 다른 파라메터 옵션을 가진 복잡한 함수에 이르기까지 무엇이든 정의할수 있습니다.

### 파라메터 복수 입력
함수는 괄호 안에서 콤마(`,`)로 구분되는 복수의 입력 파라메터를 가질수 있습니다.
이 함수는 반개영역(half-open range)의 시작과 끝의 인덱스를 받아 얼마나 많은 요소(elements)들이 영역안에 있는지 계산합니다:
```
func halfOpenRangeLength(start: Int, end: Int) -> Int {
return end - start
}
println(halfOpenRangeLength(1, 10))
// prints "9"
```
### 파라메터가 없는 함수
함수에 입력 파라메터를 정의할 필요는 없습니다. 밑의 예제는 입력 파라메터가 없는 함수입니다. 이 함수는 호출될때마다 언제나 같은 메시지를 반환합니다.
```
func sayHelloWorld() -> String {
return "hello, world"
}
println(sayHelloWorld())
// prints "hello, world"
```
함수 정의는 아무런 파라메터를 받지 않는다고 해도 함수 이름뒤에 여전히 괄호를 포함해야 합니다. 함수가 호출될 때도 함수 이름뒤에 빈 괄호 한쌍이 따라와야을 표시해야 합니다.

### 반환값이 없는 함수
함수에 반환 타입을 정의할 필요는 없습니다. 밑의 예제는 `sayHello`의 `waveGoodbye`라 불리는 버전입니다. 값을 반환하지 않고 자신의 `String`값을 출력합니다.
```
func sayGoodbye(personName: String) {
println("Goodbye, ` \(personName)! ")
}
sayGoodbye("Dave")
// prints "Goodbye, Dave!"
```
반환값을 필요로 하지 않이 없기 때문에 함수 정의는 반환 화살표(return arrow`->`)나 반환 타입을 포함하지 않습니다.

> NOTE
엄밀히 말하자면, `sayGoodbye` 함수는 반환값이 정의되어있지 않아도 여전히 반환값을 가집니다. 반환값이 정의되어있지 않은 함수는 `Void`타입의 특수값을 반환합니다. '`()'`로 쓰여질수 있는 단순한 빈 튜플(Tuple)이며, 사실상 요소를 갖고있지 않은 튜플입니다.

함수가 호출되었을때 함수의 반환값은 무시될수 있습니다.
```
func printAndCount(stringToPrint: String) -> Int {
println(stringToPrint)
return countElements(stringToPrint)
}
func printWithoutCounting(stringToPrint: String) {
printAndCount(stringToPrint)
}
printAndCount("hello, world")
// prints "hello, world" and returns a value of 12
printWithoutCounting("hello, world")
// prints "hello, world" but does not return a value
```
첫번째 함수인 `printAndCount`는 문자열을 출력하고 출력한 문자열의 캐릭터 갯수를 세서 Int 타입으로 반환합니다. 두번째 함수인 `printWithoutCounting`은 첫번째 함수를 호출합니다. 하지만 반환값은 무시합니다. 두번째 함수가 호출되면 메시지는 첫번째 함수에 의해 여전히 출력되지만, 첫번째 함수의 반환값은 사용되지 않습니다.

> NOTE
반환값은 무시될수 있습니다. 하지만 함수는 언제나 값을 반환할것입니다. 반환 타입이 정의된 함수는 값을 반환하지 않은채로 함수가 실행 될수 없습니다. 그렇게 하려고 시도할 경우 컴파일 에러를 낼 것입니다.

### 여러개의 반환값을 가지는 함수
튜플 타입은 하나의 합성된 반환값으로서 함수의 반환에 사용될 수 있습니다.
아래의 예제는 `count`라는 함수의 정의입니다. 이 함수는 아메리칸 영어에서 사용되는 표준 모음과 자음을 기반으로 모음과 자음 그리고 다른 문자들을 문자열에서 셉니다.
```
func count(string: String) -> (vowels: Int, consonants: Int, others: Int) {
var vowels = 0, consonants = 0, others = 0
for character in string {
switch String(character).lowercaseString {
case "a", "e", "i ", "o", "u":
++vowels
case "b", "c", "d", "f", "g", "h", "j", "k", "l ", "m",
"n", "p", "q", "r", "s", "t", "v", "w ", "x", "y", "z":
++consonants
default:
++others
}
}
return (vowels, consonants, others)
}
```
`count` 함수를 이용함으로서 임의의 문자열의 문자 갯수를 셀수 있습니다. 그리고 세 개의 이름있는 `Int` 값으로 구성된 튜플로 그 값을 받아옵니다.
```
let total = count("some arbitrary string! ")
println("\(total.vowels) vowels and \(total.consonants) consonants")
// prints "6 vowels and 13 consonants"
```
튜플의 멤버들은 함수 내에서 반환할때 이름을 지을 필요가 없습니다. 함수 정의시에 함수의 반환 타입에 이미 명시가 되어있기 때문입니다.

## 함수 파라메터 이름
위의 모든 함수들은 함수 자신의 파라메터로 파라메터 이름을 정의하고 있습니다.
```
func someFunction(parameterName: Int) {
// function body goes here, and can use parameterName
// to refer to the argument value for that parameter
}
```
하지만 그러한 파라메터 이름들은 오직 함수 자신의 몸체(Body) 안에서만 사용될 수 있습니다. 또한 함수를 호출할때는 사용할 수 없습니다. 그러한 종류의 파라메터 이름은 지역 파라메터 이름(local parameter names)이라고 합니다. 오직 함수의 내부(Body)에서만 사용할 수 있기 때문입니다.

### 외부 파라메터 이름(External Parameter Names)
때때로 각각의 파라메터의 이름을 함수를 호출할때 지어주는 것이 유용할때가 있습니다. 함수에게 어떤 인수가 어떤 목적인지 지시하기 위해서죠.
만약 당신이 만든 함수를 사용하려는함수 사용자에게 파라메터 이름을 제공하고 싶다면, 지역 파라메터 이름과 외부 파라메터 이름을 정의하면 됩니다. 외부 파라메터 이름은 지역 파라메터 이름 바로 앞에 공백으로 구분해서 작성합니다.
```
func someFunction(external ParameterName localParameterName: Int) {
// function body goes here, and can use local ParameterName
// to refer to the argument value for that parameter
}
```
> NOTE
만약 외부 파라메터 이름이 파라메터에 대해 제공된다면, 외부 파라메터 이름은 언제나 함수 호출시에 사용되어야 합니다.

예를 들어 다음과 같은 함수가 있다고 합시다. 이 함수는 두 문자열 사이에 `joiner` 문자열을 삽입해 연결하는 함수입니다.
```
func join(s1: String, s2: String, joiner: String) -> String {
return s1 + joiner + s2
}
```
이 함수를 호출할때 함수로 전달되는 세 문자열의 목적이 불분명합니다.
```
join("hello", "world", ", ")
// returns "hello, world"
```
문자열 값들의 목적을 명확하게 하기 위해, 외부 파라메터를 `join`함수의 각각의 파라메터에 정의합니다.

```
func join(string s1: String, toString s2: String, withJoiner joiner: String)
-> String {
return s1 + joiner + s2
}
```

이 버전의 join 함수에서는 첫번째 파라메터의 외부 이름은 `string`이며 지역 이름은 `s1`이다. 두번째 파라메터는 외부 이름으로 `toString`을 쓰고 지역 이름은 `s2`이다. 그리고 세번째 파라메터는 외부 이름으로 `withJoiner`를 쓰고 지역 이름은 `joiner`이다.
이제 외부 파라메터 이름을 사용하여 함수를 호출할때 명확하고 애매하지 않은 방법으로 호출할 수 있게 되었다.
```
join(string: "hello", toString: "world", withJoiner: ", ")
// returns "hello, world"
```
외부 파라메터 이름의 사용은 이 두번째 `join`함수를 명시적이며 말이 되는(sentence-like) 방법으로 사용자들이 호출할 수 있게 합니다. 함수 몸체는 여전히 가독성이 좋고 명확한 의도를 가진채 말이죠. (whi le sti l ll providing a function body that is readable and clear in intent.)

>NOTE
누군가가 당신의 코드를 처음 보았을때 명확하지 않을 수 있다면 외부 파라메터 이름을 쓰는것을 언제나 고려하십시오. 만약 함수가 호출될때 각각의 파라메터들의 목적이 명확하고 모호하지 않다면 외부 파라메터 이름을 정할 필요는 없습니다.

### 단축 외부 파라메터 이름
만약 함수의 외부 파라메터 이름을 제공하려 할때 이미 해당 파라메터의 내부 이름(local parameter name)이 이미 적절한 이름을 가지고 있다면, 똑같은 이름을 두번 쓸 필요가 없습니다. 대신 파라메터 이름을 한번 쓰고, 이름의 접두어로 해시 심볼(hash symbol) (`#`)을 붙입니다. 이렇게 함으로서 스위프트는 해당 이름을 외부 파라메터 이름과 지역 파라메터 이름으로 동시에 쓰게 될 것이됩니다.
이 예제는 `containsCharacter` 함수를 정의하고 호출합니다. 해당 함수는 두 입력 파라메터에 `#`을 붙여서 같은 이름으로 외부 파라메터 이름과 내부 파라메터 이름으로 쓰이게 하였했습니다.
```
func containsCharacter(#string: String, #characterToFind: Character) -> Bool {
for character in string {
if character == characterToFind {
return true
}
}
return false
}
```
이 함수의 파라메터 이름 선정은 함수 몸체를 명확하고 가독성있게 하며 동시에 함수 호출에 모호함이 없게 하였했습니다.
```
let containsAVee = containsCharacter(string: "aardvark", characterToFind: "v")
// containsAVee equals true, because "aardvark" contai ns a "v"
```
### 기본(default) 파라메터 값
함수 정의의 일부로서 파라메터의 기본 값을 지정해줄 수 있다. 기본값이 지정되어 있으면 함수를 호출할때 해당 파라메터를 생략할 수 있다.

>NOTE
기본값을 가지는 파라메터는 함수의 파라메터 리스트에서 마지막에 둔다. 이렇게 함으로써 함수 호출이 기본값을 가지지 않는 파라메터들이 언제나 같은 순서임을 보장할 수 있고, 매번 함수가 호출될 때마다 같은 함수가 호출되게 한다.

이 함수는 앞서 보인 `join`함수의 `joiner` 파라메터에 기본값을 부여한 버전이 있입니다.
```
func join(string s1: String, toString s2: String, withJoiner joiner: String = " ")
-> String {
return s1 + joiner + s2
}
```
만약 `join`함수의 `joiner` 문자열 값이 주어지면, 앞서 보았던 것처럼 해당 문자열 값이 두 문자열을 붙이는데 사용됩니다.
```
join(string: "hello", toString: "world", withJoiner: "-")
// returns "hello-world
```
하지만 아무런 값이 `joiner`에 주어지지 않는다면, 기본값인 공백 한칸 (`" "`)이 대신 사용됩니다.
```
join(string: "hello", toString: "world")
// returns "hello world"
```
### 기본값을 가지는 외부 파라메터 이름
대부분의 경우 외부 파라메터 이름에 기본값을 제공(외부 파라메터이기에 요구되기도 하는)하는 것은 유용하다. 그렇게 함으로써 함수가 호출될때 인수가 파라메터에 대해 가지는 목적이 명확해진다.
이 과정을 쉽게 하기위해, 외부 이름을 부여하지 않은 파라메터에 대해 스위프트는 자동 외부 이름을 기본값이 정의되어 있는 파라메터에 대해 제공한다. 자동 외부 이름은 지역 이름과 똑같다. 앞서 본 해시 심볼(`#`)을 사용한 것처럼.
여기에 `joiner` 문자열 값에 기본값을 부여하였지만, 파라메터 일체에 외부 파라메터 이름은 주지 않은 버전의 `join`함수가 있다.
```
func join(s1: String, s2: String, joiner: String = " ") -> String {
return s1 + joiner + s2
}
```
이 경우에 스위프트는 자동적으로 외부 파라메터 이름을 기본값이 있는 파라메터 `joiner`에 대해 부여한다. 그러므로 외부 이름은 반드시 함수가 호출 될 때에 제공되어야 하며, 파라메터의 목적을 명확하고 모호하지 않게 한다.
```
join("hello", "world", joiner: "-")
// returns "hello-world"
```
>NOTE
함수를 정의할때 명시적인 외부 이름을 쓰는 것 대신에 밑줄(`_`)을 씀으로써 이 동작을 수행하지 않게 할 수 있다. 하지만 기본값을 가진 파라메터에 적절한 외부 이름을 제공하는것은 언제나 바람직하다.

### 가변 갯수(Variadic) 파라메터
가변 갯수 파라메터는 특정 타입의 값을 0개나 그 이상 받을 수 있습니다. 가변 갯수 파라메터를 사용함으로써 함수 호출시 입력 값들이 임의의 갯수가 될수 있다고 정할 수 있습니다. 파라메터의 타입 이름의 뒤에 마침표 세개(`...`)를 삽입하는 것으로 가변 갯수 파라메터를 작성할 수 있습니다.
가변 갯수 파라메터로 함수의 내부에 전달된 값들은 적절한 타입의 배열(`array`)로 만들어진다. 예를 들어 `numbers`라는 이름의 가변 갯수 파라메터의 타입이 `Double...`이라면 함수의 내부에서는 `Double[]`타입의 `numbers` 이름을 가진 배열로 만들어지는 것이다.
밑의 예제는 평균이라 불리는 산술 평균(arithmetic mean)을 임의의 갯수를 가진 숫자의 목록에서 구하는 것이다.
```
func arithmeticMean(numbers: Double...) -> Double {
var total : Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8, 19)
// returns 10.0, which is the arithmetic mean of these three numbers
```
> NOTE
함수는 최대 한개의 가변 갯수 파라메터를 가질 수 있다. 그리고 가변 갯수 파라메터는 언제나 파라메터 목록의 마지막에 배치되어야 한다. 이렇게 함으로써 복수의 파라메터를 가진 함수를 호출할때 생기는 모호함을 피할 수 있다.
만약 함수의 파라메터중 하나 이상의 파라메터가 기본값을 가지고, 그와 동시에 가변 갯수 파라메터를 가진다면 가변 갯수 파라메터는 기본 값을 가지는 파라메터의 맨 마지막에 두어라.

### 상수(Constant)와 가변(Variable) 파라메터
함수의 파라메터들은 기본적으로 상수들입니다. 함수의 내부에서 파라메터의 값을 바꾸려 시도하는 것은 컴파일 에러를 냅니다. 이렇게 함으로써 실수로 파라메터를 바뀌지 않게 합니다.
하지만 때로는 함수가 파라메터의 값을 다양하게 복사하여 사용하는 것이 유용할때가 있습니다. 새로운 변수(variable)를 정의하지 않고 대신 가변 파라메터를 하나 이상 지정하여 함수 내부에서 사용할 수 있다. 가변 파라메터는 상수보다 병수처럼 사용 가능하며, 함수가 이용하는 파라메터의 변경 가능한 값의 새로운 사본을 제공한다.
가변 파라메터를 정의하려면 파라메터의 이름 앞에 `var` 키워드를 접두어로 사용한다
```
func alignRight(var string: String, count: Int, pad: Character) -> String {
let amountToPad = count - countElements(string)
for _ in 1...amountToPad {
string = pad + string
}
return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, 10, "-")
// paddedString is equal to "-----hello"
// originalString is still equal to "hello"
```
이 예제는 `alignRight`라는 함수를 새로 정의하고 있다. 이 함수는 입력 문자열을 오른쪽 가장자리로 정렬된 더 긴 출력 문자열을 만든다. 문자열의 왼쪽에 생긴 공간에는 정해진 채움 문자로 채워진다. 이 예제에서는 "hello"라는 문자열이 "-----hello"로 변환되었다.
`alignRight`함수는 입력 파라메터 `string`을 가변 파라메터로 정의하고 있다. 이것은 `string`이 지역 변수(variable)로서 사용될 수 있고, 전해받은 문자열 값으로 초기화 되며, 함수 내부에서 변경될 수 있음을 뜻한다.
이 함수는 우측 정렬된 전체 문자열 안에 얼마나 많은 채움 문자가 `string`의 왼쪽에 들어가야 할지 계산하는 것으로 시작한다. 이 값은 지역 상수인 `amountToPad`에 저장된다. 그리고 함수는 `amountToPad`만큼 `pad`문자를 존재하던 문자열의 왼쪽에 붙여넣고 그 값을 반환한다. 이러한 문자열 변경 과정에서 `string` 가변 파라메터가 사용된다.

>NOTE
가변 파라메터에 생긴 변화는 각각의 함수 호출이 끝난 뒤에는 남아있지 않는다. 또한 함수의 외부에서는 보이지(visible)않는다. 가변 파라메터는 함수 호출이 되는 동안만 유지된다.

###In-Out 파라메터
위에 설명된것과 같이 가변 파라메터는 오직 함수 자신의 내부에서만 변경 될 수 있다. 만약 함수가 파라메터의 값을 변경하고 그 변경이 함수 호출이 종료된 후에도 계속되길 원한다면, 파라메터를 _in-out_ 파라메터로 정의하면 된다.
_in-out_파라메터를 정의하기 위해서는 `inout` 키워드를 파라메터 정의의 시작점에 작성하면 된다. in-out 파라메터의 값은 함수의 _안으로_ 전달 되어, 함수에 의해 변경되고, 함수에서 다시 _나와서_ 원래의 값을 대체한다.
in-out 파라메터로 넘길 수 있는 값은 인수(argument)뿐이다. 상수나 문자 값은 in-out 파라메터로 넘겨질 수 없다. 상수나 문자값은 변경될 수 없기 때문이다. 인수를 in-out 파라메터로 넘길때 변수의 이름 바로 앞에 앰퍼샌드(`&`)를 붙여서 이 파라메터가 함수에 의해 변경될 수 있음을 표시한다.

>NOTE
In-out 파라메터는 기본값을 가질 수 없다. 또한 가변 갯수 파라메터도 `inout`으로 지정할 수 없으며 `var`나 `let`으로 표시될 수도 없다.

여기에 `swapTwoInts`라는 함수 예제가 있다. 이 함수는 두개의 in-out 정수(integer) 파라메터인 `a`와 `b`를 가지고 있다.
```
func swapTwoInts(inout a: Int, inout b: Int) {
let temporaryA = a
a = b
b = temporaryA
}
```
`swapTwoInts` 함수는 단순히 두 값을 교환하여 `b`를 `a`의 값으로 하고, `a`를 `b`의 값으로 한다. 이 함수는 `a`의 값을 임시 상수인 `temporaryA`에 저장하고, `b`의 값을 `a`로 할당한다. 그리고 `temporaryA`의 값을 `b`로 할당한다.
`swapTwoInts` 함수는 두 `Int` 타입의 변수를 가지고 서로의 값을 교환하는 함수라고 할 수 있다. 주의할것은 `someInt`와 `anotherInt`는 앰퍼샌드 접두어가 쓰여서 함수에 전달되었다는 것이다.
```
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// prints "someInt is now 107, and anotherInt is now 3"
```
위의 예제는 `someInt`와 `anotherInt`가 함수 외부에서 정의되었음에도, 그 값이 `swapTwoInts` 함수에 의해 변경 되었음을 보여주고 있다.

>NOTE
In-out 파라메터는 함수가 값을 반환하는 것과 같지 않다. 위의 `swapTwoInts` 예제는 반환 타입이나 반환값을 정의하고 있지 않다. 하지만 `someInt`와 `anotherInt`의 값을 변경한다. In-out 파라메터는 함수가 함수 밖의 범위(scope)에 영향을 끼칠 수 있는 또다른 방법이다.

##함수 타입
모든 함수들은 특유의 함수 타입을 가지고 있다. 함수 타입은 함수의 파라메터 타입들과 반환 타입으로 구성된다.
예를 들자면 이렇다:
```
func addTwoInts(a: Int, b: Int) -> Int {
return a + b
}
func multiplyTwoInts(a: Int, b: Int) -> Int {
return a * b
}
```
이 예제는 `addTwoInts`와 `multiplyTwoInts`, 두개의 단순한 수학 함수를 정의한다. 함수들은 각각 두개의 `Int`값을 취하고 `Int`값을 계산의 적절한 결과로서 반환한다.
위 두 함수의 타입은 `(Int, Int) -> Int`다. 이것은 "함수 타입은 `Int`타입의 파라메터가 두개며 반환값의 타입은 `Int`다." 라고 말할 수 있다.
여기의 또다른 예제는 파라메터나 반환값이 없는 함수다.
```
func printHelloWorld() {
println("hello, world")
}
```
이 함수의 타입은 `()->()`이며, "함수는 파라메터가 없고 `Void`를 반환한다."고 할 수 있다. 반환값을 정해지지 않은 함수는 언제나 `Void`를 반환하며, 이는 빈 튜플인 `()`로 표시될 수 있다.

###함수 타입을 사용하기
스위프트의 다른 타입들처럼 함수 타입 역시 사용될 수 있다. 예를들어 함수 타입의 상수나 변수를 만들어서 적절한 함수를 할당할 수 있다.
```
var mathFunction: (Int, Int) -> Int = addTwoInts
```
위 코드는 "두개의 `Int` 값을 취하며 `Int`값을 반환하는 함수 타입 `mathFuntion`을 정의한다. 이 새로운 변수가 `addTwoInts` 함수를 참조(refer)하도록 한다."고 할 수 있다.
`addTwoInts` 함수는 `mathFunction`변수와 같은 타입이다. 따라서 스위프트의 타입 체커에 의해 할당이 허용된다.
이제 `mathFunction`을 이용해 할당된 함수를 호출할 수 있다.
```
println("Result: \(mathFunction(2, 3))")
// prints "Result: 5"
```
함수 타입이 아닌 변수가 그러하듯이, 일치하는 타입의 다른 함수 또한 같은 변수에 할당 될 수 있다.
```
mathFunction = multiplyTwoInts
println("Result: \(mathFunction(2, 3))")
// prints "Result: 6"
```
다른 타입과 마찬가지로, 함수를 상수나 변수에 할당할때 스위프트가 타입을 추론하게 내버려 둘 수 있다.
```
let anotherMathFunction = addTwoInts
// anotherMathFunction is inferred to be of type (Int, Int) -> Int페
```
###파라메터 타입으로서의 함수 타입
`(Int, Int) -> Int`와 같은 함수 타입을 파라메터 타입으로 함수에 이용할 수 있다. 이로서 함수 구현의 일부를 함수가 호출 될때 함수를 호출하는 쪽에 맡기는 것이 가능하게 된다.
이 예제는 위에서 가져온 수학 함수의 결과를 출력한다.
```
func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// prints "Result: 8"
```
이 예제는 세개의 파라메터를 가지는 `printMathResult`함수를 정의한다. 첫번째 파라메터는 타입이 `(Int, Int) -> Int`인 `mathFunction`이다. 함수 타입이 맞는 함수라면 인수로서 첫번째 파라메터에 어느것이나 넘길 수 있다. 두번째와 세번째 파라메터는 `a`와 `b`이며 둘 다 `Int`타입이다. 이 둘은 제공된 수학 함수의 두 입력값으로 사용된다.
`printMathResult` 함수가 호출되면 `addTwoInts`함수와, 정수 값으로 `3`과 `5`를 넘긴다. 이 함수는 제공받은 함수를 호출할때 `3`과 `5`를 이용한다. 그리고 결과인 `8`을 출력한다.
`printMathResult`의 역할은 적절한 타입의 수학 함수의 실행 결과를 출력하는 것이다. 이 함수는 넘겨받는 함수의 구현이 실제로 무엇을 하는지 상관하지 않는다. 오직 함수가 정확하게 일치하는 타입인지만 본다. 이로서 `printMathResult`함수가 타입에 안전한 방식(type-safe way)으로 자신의 기능의 일부를 호출자에게 넘길 수 있게 한다.

###함수 타입과 반환 타입
함수 타입을 다른 함수의 반환 타입으로 사용할 수 있다. 이는 완전한 함수 타입을 반환할 함수 정의의 반환 화살표 (`->`)바로 뒤에 작성함으로서 할 수 있다.
다음 예제는 두개의 간단한 함수인 `stepForward`와 `stepBackward`를 정의하고 있다. `stepForward`함수는 입력값보다 1이 더 큰 값을 반환하고 `stepBackward`함수는 입력 값보다 1이 작은 값을 반환한다. 두 함수의 타입은 모두 `(Int) -> Int`다.
```
func stepForward(input: Int) -> Int {
return input + 1
}
func stepBackward(input: Int) -> Int {
return input - 1
}
```
여기 `chooseStepFunction` 함수가 있다. 이 함수의 반환 타입은 "`(Int) -> Int`를 반환하는 함수"다. `chooseStepFunction`은 `backwards` 불리언 파라메터에 따라 `stepForward`함수와 `stepBackward`함수중 하나를 반환한다.
```
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
return backwards ? stepBackward : stepForward
}
```
`chooseStepFunction`를 이용하여 어느 한쪽 방향으로 나아가는(증가 또는 감소하는) 함수를 얻을 수 있다.
```
var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the stepBackward() function
```
앞서 한 예제들은 `currentValue`변수에 따라 점진적으로 0이 되기 위해 필요한 증가나 감소 방향을 산출한다. `currentValue > 0`은 `true`를 반환하여, `chooseStepFunction`이 `stepBackward`함수를 반환하게 한다. 반환된 함수에 대한 참조(reference)는 `moveNearerToZero` 상수에 저장된다.
Now that moveNearerToZero refers to the correct function, it can be used to count to zero:
이제 `moveNearerToZero`가 올바른 함수를 참조하기에, 이를 0까지 세는데 이용할 수 있다.
```
println("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
println("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// 3...
// 2...
// 1...
// zero!
```
##중첩된 함수들
여기까지 이 챕터에서 마주친 모든 함수들은 모두 전역 범위(global scope)에 정의된 _전역 함수_의 예제였다. 또한 _중첩된 함수_라 불리는, 함수 내부에 다른 함수를 정의할 수 있다.
중첩 함수는 범위 밖의 세계에서 기본적으로 숨겨져 있다. 하지만 감싸고 있는 함수에 의해 여전히 이용될 수 있다. 감싸고 있는 함수는 중첩된 함수들을 반환하여 다른 범위에서 함수가 사용될 수 있게 할 수 있다.
위 예제의 `chooseStepFunction`을 다음과 같이 중첩된 함수를 이용하여 재작성 할 수 있
집니다.
이 과정을 쉽게 하기위해, 외부 이름을 부여하지 않은 파라메터에 대해 스위프트는 자동 외부 이름을 기본값이 정의되어 있는 파라메터에 대해 제공합니다. 자동 외부 이름은 앞서 본 해시 심볼(`#`)을 사용한 것처럼, 지역 이름과 똑같은 이름이 됩니다.
여기에 `joiner` 문자열 값에 기본값을 부여하였지만, 파라메터 일체에 외부 파라메터 이름은 주지 않은 버전의 `join`함수가 있습니다.
```
func join(s1: String, s2: String, joiner: String = " ") -> String {
return s1 + joiner + s2
}
```
이 경우에 스위프트는 자동적으로 외부 파라메터 이름을 기본값이 있는 파라메터 `joiner`에 대해 부여합니다. 그러므로 외부 이름은 반드시 함수가 호출 될 때에 제공되어야 하며, 파라메터의 목적을 명확하고 모호하지 않게 합니다.
```
join("hello", "world", joiner: "-")
// returns "hello-world"
```
>NOTE
함수를 정의할때 명시적인 외부 이름을 쓰는 것 대신에 밑줄(`_`)을 씀으로써 이 동작을 수행하지 않게 할 수 있습니다. 하지만 기본값을 가진 파라메터에 적절한 외부 이름을 제공하는것은 언제나 바람직합니다.

### 가변 갯수(Variadic) 파라메터
가변 갯수 파라메터는 특정 타입의 값을 0개 이상 받을 수 있습니다. 가변 갯수 파라메터를 사용함으로써 함수 호출시 입력 값들이 임의의 갯수가 될수 있다고 정할 수 있습니다. 파라메터의 타입 이름의 뒤에 마침표 세개(`...`)를 삽입하는 것으로 가변 갯수 파라메터를 작성할 수 있습니다.
가변 갯수 파라메터로 함수의 내부에 전달된 값들은 적절한 타입의 배열(`array`)로 만들어집니다. 예를 들어 `numbers`라는 이름의 가변 갯수 파라메터의 타입이 `Double...`이라면 함수의 내부에서는 `Double[]`타입의 `numbers` 이름을 가진 배열로 만들어집니다.
밑의 예제는 평균이라 불리는 산술 평균(arithmetic mean)을 임의의 갯수를 가진 숫자의 목록에서 구합니다.
```
func arithmeticMean(numbers: Double...) -> Double {
var total : Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8, 19)
// returns 10.0, which is the arithmetic mean of these three numbers
```
> NOTE
함수는 최대 한개의 가변 갯수 파라메터를 가질 수 있습니다. 그리고 가변 갯수 파라메터는 언제나 파라메터 목록의 마지막에 배치되어야 합니다. 이렇게 함으로써 복수의 파라메터를 가진 함수를 호출할때 생기는 모호함을 피할 수 있습니다.
만약 함수의 파라메터중 하나 이상의 파라메터가 기본값을 가지고, 그와 동시에 가변 갯수 파라메터를 가진다면 가변 갯수 파라메터는 기본 값을 가지는 파라메터의 맨 마지막에 두어야합니다.

### 상수(Constant)와 가변(Variable) 파라메터
함수의 파라메터들은 기본적으로 상수들입니다. 함수의 내부에서 파라메터의 값을 바꾸려 시도하는 것은 컴파일 에러를 냅니다. 이렇게 함으로써 실수로 파라메터가 바뀌지 않게 합니다.
하지만 때로는 함수가 파라메터의 값을 복사하여 다양하게 사용하는 것이 유용할때가 있습니다. 새로운 변수(variable)를 정의하지 않고 대신 가변 파라메터를 하나 이상 지정하여 함수 내부에서 사용할 수 있습니다. 가변 파라메터는 상수보다는 변수처럼 사용 가능하며, 함수가 이용하는 파라메터의 변경 가능한 사본을 제공합니다.
가변 파라메터를 정의하려면 파라메터의 이름 앞에 `var` 키워드를 접두어로 사용합니다.
```
func alignRight(var string: String, count: Int, pad: Character) -> String {
let amountToPad = count - countElements(string)
for _ in 1...amountToPad {
string = pad + string
}
return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, 10, "-")
// paddedString is equal to "-----hello"
// originalString is still equal to "hello"
```
이 예제는 `alignRight`라는 함수를 새로 정의하고 있습니다. 이 함수는 입력 문자열을 오른쪽 가장자리로 정렬하고 더 긴 출력 문자열을 만듭니다. 문자열의 왼쪽에 생긴 공간에는 정해진 채움 문자로 채워집니다. 이 예제에서는 "hello"라는 문자열이 "-----hello"로 변환되었습니다.
`alignRight`함수는 입력 파라메터 `string`을 가변 파라메터로 정의하고, `string`이 지역 변수(variable)로서 사용될 수 있는 문자열 값으로 초기화 되며, 함수 내부에서 변경될 수 있습니다.
이 함수는 우측 정렬된 전체 문자열 안에 얼마나 많은 채움 문자가 `string`의 왼쪽에 들어가야 할지 계산하는 것으로 시작합니다. 이 값은 지역 상수인 `amountToPad`에 저장됩니다. 그리고 함수는 `amountToPad`만큼 `pad`문자를 기존 문자열의 왼쪽에 붙여넣고 그 값을 반환합니다. 이러한 문자열 변경 과정에서 `string` 가변 파라메터가 사용됩니다.

>NOTE
가변 파라메터에 생긴 변화는 각각의 함수 호출이 끝난 뒤에는 남아있지 않습니다. 또한 함수의 외부에서는 보이지(visible)않습니다. 가변 파라메터는 함수 호출이 되는 동안만 유지됩니다.

###입출력(In-Out)파라메터
위에 설명 된 것과 같이 가변 파라메터는 오직 함수 자신의 내부에서만 변경 될 수 있습니다. 만약 함수가 파라메터의 값을 변경하고 그 변경이 함수 호출이 종료된 후에도 계속되길 원한다면, 파라메터를 _입출력_ 파라메터로 정의하면 됩니다.
_입출력_파라메터를 정의하기 위해서는 `inout` 키워드를 파라메터 정의의 시작점에 작성하면 됩니다. 입출력 파라메터의 값은 함수의 _안으로_ 전달 되어, 함수에 의해 변경되고, 함수에서 다시 _나와서_ 원래의 값을 대체합니다.
입출력 파라메터로 넘길 수 있는 값은 인수(argument)뿐입니다. 상수나 문자 값은 입출력 파라메터로 넘겨질 수 없습니다. 상수나 문자값은 변경될 수 없기 때문입니다. 인수를 입출력 파라메터로 넘길때 변수의 이름 바로 앞에 앰퍼샌드(`&`)를 붙여서 이 파라메터가 함수에 의해 변경될 수 있음을 표시합니다.

>NOTE
입출력 파라메터는 기본값을 가질 수 없습니다. 또한 가변 갯수 파라메터도 `inout`으로 지정할 수 없으며 `var`나 `let`으로 표시될 수도 없습니다.

여기에 `swapTwoInts`라는 함수 예제가 있습니다. 이 함수는 두개의입출력 정수(integer) 파라메터인 `a`와 `b`를 가지고 있습니다.
```
func swapTwoInts(inout a: Int, inout b: Int) {
let temporaryA = a
a = b
b = temporaryA
}
```
`swapTwoInts` 함수는 단순히 두 값을 교환하여 `b`를 `a`의 값으로 하고, `a`를 `b`의 값으로 합니다. 이 함수는 `a`의 값을 임시 상수인 `temporaryA`에 저장하고, `b`의 값을 `a`로 할당합니다. 그리고 `temporaryA`의 값을 `b`로 할당합니다.
`swapTwoInts` 함수는 두 `Int` 타입의 변수를 가지고 서로의 값을 교환하는 함수라고 할 수 있습니다다. 주의할것은 `someInt`와 `anotherInt`는 앰퍼샌드 접두어가 쓰여서 함수에 전달되었다는 것입니다.
```
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// prints "someInt is now 107, and anotherInt is now 3"
```
위의 예제는 `someInt`와 `anotherInt`가 함수 외부에서 정의되었음에도, 그 값이 `swapTwoInts` 함수에 의해 변경 되었음을 보여주고 있습니다.

>NOTE
입출력 파라메터는 함수가 값을 반환하는 것이 아닙니다. 위의 `swapTwoInts` 예제는 반환 타입이나 반환값을 정의하고 있지 않습니다. 하지만 `someInt`와 `anotherInt`의 값을 변경하죠. 입출력 파라메터는 함수가 함수 밖의 범위(scope)에 영향을 끼칠 수 있는 또다른 방법입니다.

##함수 타입
모든 함수들은 특유의 함수 타입을 가지고 있습니다. 함수 타입은 함수의 파라메터 타입들과 반환 타입으로 구성됩니다.
예를 들면 이렇습니다.
```
func addTwoInts(a: Int, b: Int) -> Int {
return a + b
}
func multiplyTwoInts(a: Int, b: Int) -> Int {
return a * b
}
```
이 예제는 `addTwoInts`와 `multiplyTwoInts`, 두개의 단순한 수학 함수를 정의합니다. 함수들은 각각 두개의 `Int`값을 취하고 `Int`값을 계산의 적절한 결과로서 반환합니다.
위 두 함수의 타입은 `(Int, Int) -> Int`입니다. 이것을 "함수 타입은 `Int`타입의 파라메터가 두개며 반환값의 타입은 `Int`다." 라고 말할 수 있습니다.
여기의 또다른 예제는 파라메터나 반환값이 없는 함수입니다.
```
func printHelloWorld() {
println("hello, world")
}
```
이 함수의 타입은 `()->()`이며, "함수는 파라메터가 없고 `Void`를 반환한다."고 할 수 있습니다. 반환값이 정해지지 않은 함수는 언제나 `Void`를 반환하며, 이는 빈 튜플인 `()`로 표시될 수 있습니다.

###함수 타입을 사용하기
함수 타입 역시 스위프트의 다른 타입들처럼 사용될 수 있습니다. 예를들어 함수 타입의 상수나 변수를 만들어서 적절한 함수를 할당할 수 있습니다.
```
var mathFunction: (Int, Int) -> Int = addTwoInts
```
위 코드는 "두개의 `Int` 값을 취하며 `Int`값을 반환하는 함수 타입 `mathFuntion`을 정의하고, 이 새로운 변수가 `addTwoInts` 함수를 참조(refer)하도록 한다."고 할 수 있습니다.
위에서 본 `addTwoInts` 함수는 `mathFunction`변수와 같은 타입입니다. 따라서 스위프트의 타입 체커에 의해 할당이 허용되죠.
이제 `mathFunction`을 이용해 할당된 함수를 호출할 수 있습니다.
```
println("Result: \(mathFunction(2, 3))")
// prints "Result: 5"
```
함수 타입이 아닌 변수가 그러하듯이, 일치하는 타입의 다른 함수 또한 같은 변수에 할당 될 수 있다.
```
mathFunction = multiplyTwoInts
println("Result: \(mathFunction(2, 3))")
// prints "Result: 6"
```
다른 타입과 마찬가지로, 함수를 상수나 변수에 할당할때 스위프트가 타입을 추론하게 내버려 둘 수 있다.
```
let anotherMathFunction = addTwoInts
// anotherMathFunction is inferred to be of type (Int, Int) -> Int페
```
###파라메터 타입으로서의 함수 타입
`(Int, Int) -> Int`와 같은 함수 타입을 파라메터 타입으로 함수에 이용할 수 있다. 이로서 함수 구현의 일부를 함수가 호출 될때 함수를 호출하는 쪽에 맡기는 것이 가능하게 된다.
이 예제는 위에서 가져온 수학 함수의 결과를 출력한다.
```
func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// prints "Result: 8"
```
이 예제는 세 개의 파라메터를 가지는 `printMathResult`함수를 정의합니다. 첫번째 파라메터는 타입이 `(Int, Int) -> Int`인 `mathFunction`입니다. 함수 타입이 맞는 함수라면 인수로서 첫번째 파라메터에 어느것이나 넘길 수 있습니다. 두번째와 세번째 파라메터는 `a`와 `b`이며 둘 다 `Int`타입입니다. 이 둘은 제공된 수학 함수의 두 입력값으로 사용됩니다.
`printMathResult` 함수가 호출되면 `addTwoInts`함수와, 정수 값으로 `3`과 `5`를 넘깁니다. 이 함수는 제공받은 함수를 호출할때 `3`과 `5`를 이용합니다. 그리고 결과인 `8`을 출력합니다.
`printMathResult`의 역할은 적절한 타입의 수학 함수의 실행 결과를 출력하는 것입니다. 이 함수는 넘겨받는 함수의 구현이 실제로 무엇을 하는지 상관하지 않습니다. 오직 함수가 정확하게 일치하는 타입인지만 봅니다. 이로써 `printMathResult`함수가 타입에 안전한 방식(type-safe way)으로 자기 기능의 일부를 호출자에게 넘길 수 있게 됩니다.

###함수 타입과 반환 타입
함수 타입을 다른 함수의 반환 타입으로 사용할 수 있습니다. 이는 완전한 함수 타입을 반환할 함수 정의의 반환 화살표 (`->`)바로 뒤에 작성함으로서 할 수 있습니다.
다음 예제는 두개의 간단한 함수인 `stepForward`와 `stepBackward`를 정의하고 있습니다. `stepForward`함수는 입력값보다 1이 더 큰 값을 반환하고 `stepBackward`함수는 입력 값보다 1이 작은 값을 반환합니다. 두 함수의 타입은 모두 `(Int) -> Int`입니다.
```
func stepForward(input: Int) -> Int {
return input + 1
}
func stepBackward(input: Int) -> Int {
return input - 1
}
```
여기 `chooseStepFunction` 함수가 있습니다. 이 함수의 반환 타입은 "`(Int) -> Int`를 반환하는 함수"입니다. `chooseStepFunction`은 `backwards` 불리언 파라메터에 따라 `stepForward`함수와 `stepBackward`함수중 하나를 반환합니다.
```
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
return backwards ? stepBackward : stepForward
}
```
`chooseStepFunction`를 이용하여 어느 한쪽 방향으로 나아가는(증가 또는 감소하는) 함수를 얻을 수 있다.
```
var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the stepBackward() function
```
앞서 한 예제들은 `currentValue`변수에 따라 점진적으로 0이 되기 위해 필요한 증가나 감소 방향을 산출한다.`currentValue`의 초기값은 `3`이며, 이는 곧 `currentValue > 0`은 `true`를 반환하게 합니다. 그리고 `chooseStepFunction`이 `stepBackward`함수를 반환하게 합니다. 반환된 함수에 대한 참조(reference)는 `moveNearerToZero` 상수에 저장됩니다.
이제 `moveNearerToZero`가 올바른 함수를 참조하게 되었기에, 0까지 세는데 이용할 수 있습니다.
```
println("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
println("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// 3...
// 2...
// 1...
// zero!
```
##중첩된 함수들
여기까지 이 챕터에서 마주친 모든 함수들은 모두 전역 범위(global scope)에 정의된 _전역 함수_의 예제였습니다. 또한 _중첩된 함수_라 불리는, 함수 내부에 다른 함수를 정의할 수 있습니다.
중첩 함수는 범위 밖의 세계에서 기본적으로 숨겨져 있습니다. 하지만 감싸고 있는 함수에 의해 여전히 이용될 수 있습니다. 감싸고 있는 함수는 중첩된 함수들을 반환하여 다른 범위에서 함수가 사용될 수 있게 할 수 있습니다.
위 예제의 `chooseStepFunction`을 다음과 같이 중첩된 함수를 이용하여 재작성 할 수 있습니
다.
```
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backwards ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
println("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!
```
translator
# Translator
번역에 힘 써주신 고마우신 분들
업데이트 예정.입니다.