Merge changes from master into Seoh

Seoh Cha authored
revision bf990cb7fd04bf3620ac97ae9b474d6b3558fd67
About
# Apple Swift Programming Language PDF translation for KOREAN
This is a [Swift](https://developer.apple.com/swift/) guide documentation translation project.
Feel free to participate project =)
> 이 프로젝트는 애플의 새로운 프로그래밍 언어 **swift** 번역 프로젝트입니다. 자유롭게 참여하세요 =)

## Downloads
- [Download “The Swift Programming Language” from the iBooks Store](https://itunes.apple.com/us/book/the-swift-programming-language/id881256329?mt=11)
- [Download "The Swift Programming Language" from private dropbox](https://www.dropbox.com/s/rd79pw1bhhvg22h/the-swift-rogramming-language.pdf)

## 계획
업데이트 예정

## Rule
- 문서 작성은 개인 version에서 작업 한뒤 pull request로 merge 합니다.
**“Apple Inc. Copyright © 2014 Apple Inc. All rights reserved.”**
This is a [The Swift Programming Language](https://developer.apple.com/swift/) guide documentation translation project.

_This project is **never used for commercial purposes**.
By translating "The Swift Programming Language" we want to help a lot of korean learners who may otherwise struggle to understand it._

> 이 프로젝트는 애플의 새로운 프로그래밍 언어 **swift** 번역 프로젝트입니다. 자유롭게 참여하세요 =)
**이 번역 프로젝트는 절대로 상업적인 목적으로 사용되지 않습니다.**

## Downloads
- [Download “The Swift Programming Language” from the iBooks Store](https://itunes.apple.com/us/book/the-swift-programming-language/id881256329?mt=11)
- [Download "The Swift Programming Language" from private dropbox](https://www.dropbox.com/s/rd79pw1bhhvg22h/the-swift-rogramming-language.pdf)

## 현재 번역 상태
- _**두껍고 이탤릭의**_ 글씨는 번역이 1차적으로 완료 된 페이지 입니다. 오역이나 더 나은 표현이 있을 경우에는 [Discussion](https://www.penflip.com/jjuakim/swift-korean/discussions)페이지에 가셔서 해당 chapter를 찾고 같이 이야기를 나눠보세요.
- 일단 `Chapter 25` 까지 우선적으로 번역할 예정입니다.
- Chapter 25까지 번역 후 P.R로 피드백 수렴하면서 뒷부분(Chapter 26~ ) 번역을 진행하겠습니다.
- `@멘션` 표시가 없는 챕터는 아직 할당되지 않은 챕터입니다. [Discussion-챕터 분배 (얼른 와서 찜하세요)](https://www.penflip.com/jjuakim/swift-korean/discussions/2) 에 가서 원하는 챕터를 `댓글`로 찜 하세요! 확인후 운영자가 `assign` 해드립니다

## 작업 할당
01. _**Swift에 대해서 by @FlashMaestro**_
02. Swift 둘러보기 (Assign to @FlashMaestro)
03. 기초 다지기 (Assign to @FlashMaestro)
04. 기본 연산자 (Assign to @Nirvana)
05. 문자열과 문자 (Assign to @Nirvana)
06. 컬렉션 타입 (Assign to @justinchronicle)
07. 통제 흐름 (Assign to @nassol)
08. 함수 (Assign to @Quartet)
09. 클로저(Closures) (Assign to @inureyes)
10. 열거형 (Assign to @inureyes )
11. 클래스와 구조체 (Assign to @seanmoon)
12. 속성 (Assign to @mango)
13. 메서드 (Assign to @northPenguin)
14. 서브 스크립트 (Assign to @Snowcat8436)
15. 상속 (Assign to @hoppingbonny)
16. 초기화 (Assign to @qwneed)
17. 해제(Deinitialization) (Assign to @qwneed)
18. 자동 참조 계수(ARC) (Assign to @RoyTheGame)
19. 옵션 연쇄 (Assign to @hyukhur)
20. 타입 변환 (Assign to @Snowcat8436)
21. 내부 타입 (Assign to @jjuakim)
22. 확장 (Assign to @easthelper)
23. 프로토콜
24. 제네릭 (Assign to @eonil)
25. 고급 연산자 (Assign to @dyanos)


## Rule
[추가논의](https://www.penflip.com/jjuakim/swift-korean/discussions/1)는 이 곳에서..
- 문서 작성은 개인 version에서 작업 한뒤 pull request로 merge 합니다.

## Translation Guide
[추가논의](https://www.penflip.com/jjuakim/swift-korean/discussions/1)는 이 곳에서..
- 담당 부분에서 최초 등장 용어에 영문을 함께 표기. 그 이후로는 번역단어로만 표기
> Ex) (최초) 함수(Function)란 xxxx -> (이후) 함수는 xxxx

Contents
> These files will be included in your book:

About.txt
chapter1.txt
chapter2.txt
chapter3.txt
chapter4.txt
chapter5.txt
chapter6.txt
chapter7.txt
chapter8.txt
chapter9.txt
chapter10.txt
chapter11.txt
chapter12.txt
chapter13.txt
chapter14.txt
chapter15.txt
chapter16.txt
chapter17.txt
chapter18.txt
chapter19.txt
chapter20.txt
chapter21.txt
chapter22.txt
chapter23.txt
chapter24.txt
chapter25.txt
chapter26.txt
chapter27.txt
chapter1
# 01 Swift에 대해서

Swift는 C언어 호환성에 대한 제약없이 C언어 그리고 Objective-C언어 중 최고의 것들을 기반으로 iOS와 OS X 앱을 개발하기 위한 언어입니다. Swift는 안전한 프로그래밍 패턴을 채용했고 프로그래밍을 더욱 쉽고 유연하고 재미있게 만들어주는 최신 특징들을 더했습니다. 성숙하고 많은 사랑을 받고 있는 코코아, 코코아 터치 프레임워크를 기반으로한 Swift의 이런 훌륭함은 소프트웨어 개발 방법에 대한 새로운 상상의 기회입니다.

Swift는 몇년에 걸쳐 만들어져 왔습니다. 애플은 Swift를 위한 현존하는 진보한 컴파일러, 디버거, 프레임워크 기반의 토대를 만들었습니다. 우리는 자동 레퍼런스 계수( ARC)로 메모리 관리를 단순화 했습니다. Foundation(Apple Foundation Framework)과 코코아의 견고한 기초를 기반으로 만들어진 우리의 프레임워크 스텍은 최신화와 표준화의 결과물입니다. Objective-C는 블록, 문자집합, 모듈, 혼란없는 최신 언어 기술 프레임워크 적용 가능 등을 지원하도록 발전해왔습니다. 이러한 기초작업에 감사하며 애플 소프트웨어 개발의 미래를 위한 새로운 언어를 소개합니다.

Swift는 Objective-C 개발자들에게 매우 친숙한 느낌을 줍니다. Swift가 Objective-C의 명명식 파라미터의 읽기 쉬움과 다이나믹 객체 모델의 능력을 적용했기 때문입니다. 이를 통해 끊김없는 기존 코코아 프레임워크에 대한 접근과 Objective-C와의 혼합된 상호운영을 제공합니다. 이러한 공통점을 기반으로 만들어진 Swift는 많은 새로운 특징들과 언어의 절차지향과 객체지향적 부분에 대한 통합을 도입했습니다.

Swift는 초보 프로그래머 친화적입니다. Swift는 스크립트 언어만큼이나 표현하기 쉽고 즐거운데다가 산업품질에 적합한 시스템 프로그래밍 언어입니다. Swift는 프로그래머들이 빌드하고 실행하는 낭비없이 즉기 Swift의 코드를 실험하고 결과를 볼 수 있도록하는 혁신적인 요소인 playgrounds를 지원합니다.

Swift는 폭넓은 애플 엔지니어링 문화로 부터 나온 지혜와 뜻을 같이하는 최신 언어들중 최고의 것들을 겸비하고 있습니다. 성능과 개발편리성에 대한 타협이 필요없을 만큼 컴파일러는 성능에 최적화되어 있고, 언어는 개발편리성에 최적화 되어 있습니다. Swift는 "hello, world"로부터 전체 운영체제로 확장할 수 있게 디자인 되었습니다. 이 모든것이 Swift 때문에 애플과 개발자들에게 투자할 가치가 있다고 생각하게 합니다.

Swift는 iOS와 OS X 앱을 만들고 또 계속 새로운 기능을 추가하고 개선하기 위한 환상적인 방법입니다. Swift를 향한 우리의 목표는 야심찹니다. 우리는 당신이 Swift로 무언가 만드는 것을 빨리 보고싶습니다.
chapter11
# 11 클래스와 구조체

Classes and Structures
Classes and structures are general -purpose, flexible constructs that become the bui lding
blocks of your program’s code. You define properties and methods to add functional i ty to
your classes and structures by using exactly the same syntax as for constants, variables,
and functions.
Unl ike other programming languages, Swi ft does not requi re you to create separate
interface and implementation fi les for custom classes and structures. In Swi ft, you define
a class or a structure in a single fi le, and the external interface to that class or structure i s
automati cal ly made avai lable for other code to use.
N O T E
An i nstance of a cl ass i s tradi ti onal l y know n as an object. How ever, Sw i ft cl asses and structures are much
cl oser i n functi onal i ty than i n other l anguages, and much of thi s chapter descri bes functi onal i ty that can appl y
to i nstances of ei ther a cl ass or a structure type. Because of thi s, the more general term i nstance i s used.
Comparing Classes and Structures
Classes and structures in Swi ft have many things in common. Both can:
For more information, see Properties, Methods, Subscripts, Ini tial i zation, Extensions, and
Protocol s.
Classes have addi tional capabi l i ties that structures do not:
Define properties to store values
Define methods to provide functional i ty
Define subscripts to provide access to thei r values using subscript syntax
Define ini tial i zers to set up thei r ini tial state
Be extended to expand thei r functional i ty beyond a defaul t implementation
Conform to protocol s to provide standard functional i ty of a certain kind
Inheri tance enables one class to inheri t the characteri sti cs of another.
For more information, see Inheri tance, Type Casting, Ini tial i zation, and Automati c
Reference Counting.
N O T E
Structures are al w ays copi ed w hen they are passed around i n your code, and do not use reference counti ng.
Definition Syntax
Classes and structures have a simi lar defini tion syntax. You introduce classes wi th the cl ass
keyword and structures wi th the struct keyword. Both place thei r enti re defini tion wi thin a
pai r of braces:
cl ass SomeCl ass {
// cl ass defi ni ti on goes here
클래스와 구조체는 프로그램의 코드블럭을 정의할때 사용됩니다. 여러분은 프로퍼티를 정의할수 있고 기능을 추가하기 위해 상수, 변수 그리고 함수를 정의할때와 동일한 문법적 표기로 메소드를 정의하실 수도 있습니다.
다른 프로그래밍 언어와는 달리 스위프트는 사용자 클래스와 구조체를 위해서 헤더파일과 구현파일을 나누실 필요가 없습니다. 단일파일에 선언과 구현을 하며 다른 코드에서 사용하기 위한 그 클래스와 구조체의 외부 인터페이스는 자동적으로 생성됩니다.

>NOTE
>클래스의 인스턴스는 전통적으로 오브젝트라 표기하기도 합니다. 하지만 스위프트 클래스와 구조체는 다른 언어보다도 기능적인(functionality) 측면에 중점을 두고 이 챕터에서도 클래스나 구조체의 인스턴스에 적용가능한 기능적인 면을 설명할것이기 때문에 더 일반적인 인스턴스라는 용어를 사용할것입니다(#이게 먼말이여 리뷰좀 해주세요).

## 클래스와 구조체의 비교
스위프트에서 클래스와 구조체는 여러 공통점을 가지고 있습니다. 공통점으로는
* 프로퍼티를 정의하고 값을 할당할수 있습니다.
* 메소드를 정의하고 메소드의 기능(역할)을 정의할수 있습니다.
* 접근자 문법을 통해서 할당된 값에 사용할수 있는 접근자를 정의할수 있습니다.
* 초기화를 위해 생성자를 정의할수 있습니다.
* 기본 구현에 확장가능(상속)
* 특정 종류의 표즌 기능을 제공하는 프로토콜을 준수할수 있습니다.

더 많은 정보를 원하신다면 Properties, Methods, Subscripts, Initialization, Extensions 그리고 Protocols 항목을 참조하십시오.

클래스는 구조체를 통해서는 할수없는 아래와 같은 추가적인 기능들을 지원합니다.
* 상속은 다른 클래스의 특성을 상속받는 클래스의 생성을 가능케합니다.
* 형변환은 여러분이 런타임시에 클래스의 형을 확인하고 변환을 가능케합니다.
* 소멸자는 클래스 인스턴스에 할당된 자원을 환원 가능케합니다.
* 참조카운팅은 하나의 클래스 인스턴스에 하나 이상의 참조를 가능케합니다.

더 많은 정보를 원하신다면 Inheritance, Type Casting, Initialization 그리고 Automatic Reference Counting 항목을 참조하십시오.

>NOTE
>여러분의 코드에서 구조체는 언제나 복사가 될뿐 참조카운팅을 사용하지 않습니다.

## 정의문법
클래스와 구조체는 유사한 문법적 구조를 가지고 있습니다. 클래스는 class 키워드를 구조체는 struct 키워드를 사용합니다. 둘다 그들의 정의를 중괄호({})내에 위치시킵니다.
```
class SomeClass {
// 이곳에 클래스를 정의하십시오

}

struct SomeStructure {
// structure defi ni ti on goes here
}
N O T E
Whenever you defi ne a new cl ass or structure, you effecti vel y defi ne a brand new Sw i ft type. Gi ve types
UpperCamel Case names (such as SomeCl ass and SomeStructure here) to match the capi tal i zati on of standard
Sw i ft types (such as Stri ng, Int, and Bool ). Conversel y, al w ays gi ve properti es and methods l ow erCamel Case
names (such as frameRate and i ncrementCount) to di fferenti ate them from type names.
Here’s an example of a structure defini tion and a class defini tion:
struct Resol uti on {
Type casting enables you to check and interpret the type of a class instance at
runtime.
Deini tial i zers enable an instance of a class to free up any resources i t has
assigned.
Reference counting al lows more than one reference to a class instance.
var w i dth = 0
var hei ght = 0
}
cl ass Vi deoMode {
var resol uti on = Resol uti on()
var i nterl aced = fal se
var frameRate = 0. 0
var name: Stri ng?
The example above defines a new structure cal led Resol uti on, to describe a pixel -based
di splay resolution. Thi s structure has two stored properties cal led w i dth and hei ght. Stored
properties are constants or variables that are bundled up and stored as part of the class
or structure. These two properties are inferred to be of type Int by setting them to an
ini tial integer value of 0.
The example above al so defines a new class cal led Vi deoMode, to describe a speci fi c video
mode for video di splay. Thi s class has four variable stored properties. The fi rst, resol uti on, i s
ini tial i zed wi th a new Resol uti on structure instance, whi ch infers a property type of Resol uti on.
For the other three properties, new Vi deoMode instances wi l l be ini tial i zed wi th an i nterl aced
setting of fal se (meaning “non-interlaced video”), a playback frame rate of 0. 0, and an
optional Stri ng value cal led name. The name property i s automati cal ly given a defaul t value of
ni l , or “no name value”, because i t i s of an optional type.
Class and Structure Instances
The Resol uti on structure defini tion and the Vi deoMode class defini tion only describe what a
Resol uti on or Vi deoMode wi l l look l ike. They themselves do not describe a speci fi c resolution or
video mode. To do that, you need to create an instance of the structure or class.
The syntax for creating instances i s very simi lar for both structures and classes:
l et someResol uti on = Resol uti on()
l et someVi deoMode = Vi deoMode()
Structures and classes both use ini tial i zer syntax for new instances. The simplest form of
ini tial i zer syntax uses the type name of the class or structure fol lowed by empty
parentheses, such as Resol uti on() or Vi deoMode(). Thi s creates a new instance of the class or
structure, wi th any properties ini tial i zed to thei r defaul t values. Class and structure
ini tial i zation i s described in more detai l in Ini tial i zation.
Accessing Properties
You can access the properties of an instance using dot syntax. In dot syntax, you wri te
the property name immediately after the instance name, separated by a period (.),
wi thout any spaces:
pri ntl n("T he w i dth of someResol uti on i s \(someResol uti on.w i dth)")
// pri nts "T he w i dth of someResol uti on i s 0"
In thi s example, someResol uti on.w i dth refers to the w i dth property of someResol uti on, and returns i ts
defaul t ini tial value of 0.
You can dri l l down into sub-properties, such as the w i dth property in the resol uti on property of
a Vi deoMode:
pri ntl n("T he w i dth of someVi deoMode i s \(someVi deoMode. resol uti on.w i dth)")
// pri nts "T he w i dth of someVi deoMode i s 0"
You can al so use dot syntax to assign a new value to a variable property:
someVi deoMode. resol uti on.w i dth = 1280
pri ntl n("T he w i dth of someVi deoMode i s now \(someVi deoMode. resol uti on.w i dth)")
// pri nts "T he w i dth of someVi deoMode i s now 1280"
N O T E
Unl i ke Objecti ve-C, Sw i ft enabl es you to set sub-properti es of a structure property di rectl y. In the l ast exampl e
above, the w i dth property of the resol uti on property of someVi deoMode i s set di rectl y, w i thout your needi ng to
set the enti re resol uti on property to a new val ue.
Memberwise Initializers for Structure Types
Al l structures have an automati cal ly-generated memberwi se ini tial i zer, whi ch you can use
to ini tial i ze the member properties of new structure instances. Ini tial values for the
properties of the new instance can be passed to the memberwi se ini tial i zer by name:
l et vga = Resol uti on(w i dth: 640, hei ght: 480)
Unl ike structures, class instances do not receive a defaul t memberwi se ini tial i zer.
Ini tial i zers are described in more detai l in Ini tial i zation.
Structures and Enumerations Are Value Types
A value type i s a type that i s copied when i t i s assigned to a variable or constant, or when
i t i s passed to a function.
You’ve actual ly been using value types extensively throughout the previous chapters. In
fact, al l of the basi c types in Swi ft—integers, floating-point numbers, Booleans, strings,
arrays and di ctionaries—are value types, and are implemented as structures behind the
scenes.
Al l structures and enumerations are value types in Swi ft. Thi s means that any structure
and enumeration instances you create—and any value types they have as properties—are
always copied when they are passed around in your code.
Consider thi s example, whi ch uses the Resol uti on structure from the previous example:
l et hd = Resol uti on(w i dth: 1920, hei ght: 1080)
var ci nema = hd
Thi s example declares a constant cal led hd and sets i t to a Resol uti on instance ini tial i zed
wi th the width and height of ful l HD video (1920 pixel s wide by 1080 pixel s high).
It then declares a variable cal led ci nema and sets i t to the current value of hd. Because
Resol uti on i s a structure, a copy of the exi sting instance i s made, and thi s new copy i s
assigned to ci nema. Even though hd and ci nema now have the same width and height, they
are two completely di fferent instances behind the scenes.
Next, the w i dth property of ci nema i s amended to be the width of the sl ightly-wider 2K
standard used for digi tal cinema projection (2048 pixel s wide and 1080 pixel s high):
ci nema.w i dth = 2048
Checking the w i dth property of ci nema shows that i t has indeed changed to be 2048:
pri ntl n("ci nema i s now \(ci nema.w i dth) pi xel s w i de")
// pri nts "ci nema i s now 2048 pi xel s w i de"
However, the w i dth property of the original hd instance sti l l has the old value of 1920:
pri ntl n("hd i s sti l l \(hd.w i dth) pi xel s w i de")
// pri nts "hd i s sti l l 1920 pi xel s w i de"
When ci nema was given the current value of hd, the values stored in hd were copied into the
new ci nema instance. The end resul t i s two completely separate instances, whi ch just
happened to contain the same numeri c values. Because they are separate instances,
setting the width of ci nema to 2048 doesn’t affect the width stored in hd.
The same behavior appl ies to enumerations:
enum CompassPoi nt {
case North, South, East, West
}
var currentDi recti on = CompassPoi nt.West
l et rememberedDi recti on = currentDi recti on
currentDi recti on = . East
i f rememberedDi recti on == .West {
pri ntl n("T he remembered di recti on i s sti l l .West")
}
i nts "T he remembered di recti on i s sti l l .West"
When rememberedDi recti on i s assigned the value of currentDi recti on, i t i s actual ly set to a copy of
that value. Changing the value of currentDi recti on thereafter does not affect the copy of the
original value that was stored in rememberedDi recti on.
Classes Are Reference Types
Unl ike value types, reference types are not copied when they are assigned to a variable
or constant, or when they are passed to a function. Rather than a copy, a reference to the
same exi sting instance i s used instead.
Here’s an example, using the Vi deoMode class defined above:
l et tenEi ghty = Vi deoMode()
tenEi ghty. resol uti on = hd
tenEi ghty. i nterl aced = true
tenEi ghty. name = "1080i "
tenEi ghty. frameRate = 25. 0
Thi s example declares a new constant cal led tenEi ghty and sets i t to refer to a new instance
of the Vi deoMode class. The video mode i s assigned a copy of the HD resolution of 1920 by
1080 from before. It i s set to be interlaced, and i s given a name of "1080i ". Final ly, i t i s set
to a frame rate of 25. 0 frames per second.
Next, tenEi ghty i s assigned to a new constant, cal led al soT enEi ghty, and the frame rate of
al soT enEi ghty i s modi fied:
l et al soT enEi ghty = tenEi ghty
al soT enEi ghty. frameRate = 30. 0
Because classes are reference types, tenEi ghty and al soT enEi ghty actual ly both refer to the
same Vi deoMode instance. Effectively, they are just two di fferent names for the same single
instance.
Checking the frameRate property of tenEi ghty shows that i t correctly reports the new frame
rate of 30. 0 from the underlying Vi deoMode instance:
pri ntl n("T he frameRate property of tenEi ghty i s now \(tenEi ghty. frameRate)")
// pri nts "T he frameRate property of tenEi ghty i s now 30. 0"
Note that tenEi ghty and al soT enEi ghty are declared as constants, rather than variables.
However, you can sti l l change tenEi ghty. frameRate and al soT enEi ghty. frameRate because the values
of the tenEi ghty and al soT enEi ghty constants themselves do not actual ly change. tenEi ghty and
al soT enEi ghty themselves do not “store” the Vi deoMode instance—instead, they both refer to a
Vi deoMode instance behind the scenes. It i s the frameRate property of the underlying Vi deoMode
that i s changed, not the values of the constant references to that Vi deoMode.
Identity Operators
Because classes are reference types, i t i s possible for mul tiple constants and variables to
refer to the same single instance of a class behind the scenes. (The same i s not true for
structures and enumerations, because they are value types and are always copied when
they are assigned to a constant or variable, or passed to a function.)
It can sometimes be useful to find out i f two constants or variables refer to exactly the
same instance of a class. To enable thi s, Swi ft provides two identi ty operators:
Use these operators to check whether two constants or variables refer to the same single
instance:
i f tenEi ghty === al soT enEi ghty {
pri ntl n("tenEi ghty and al soT enEi ghty refer to the same Resol uti on i nstance. ")
}
// pri nts "tenEi ghty and al soT enEi ghty refer to the same Resol uti on i nstance. "
Note that “identi cal to” (represented by three equal s signs, or ===) does not mean the
same thing as “equal to” (represented by two equal s signs, or ==):
When you define your own custom classes and structures, i t i s your responsibi l i ty to
decide what qual i fies as two instances being “equal ”. The process of defining your own
implementations of the “equal to” and “not equal to” operators i s described in
Equivalence Operators.
Pointers
If you have experience wi th C, C++, or Objective-C, you may know that these languages
use pointers to refer to addresses in memory. A Swi ft constant or variable that refers to
an instance of some reference type i s simi lar to a pointer in C, but i s not a di rect pointer
to an address in memory, and does not requi re you to wri te an asteri sk (*) to indi cate
that you are creating a reference. Instead, these references are defined l ike any other
constant or variable in Swi ft.
Identi cal to (===)
Not identi cal to (! ==)
“Identi cal to” means that two constants or variables of class type refer to exactly
the same class instance.
“Equal to” means that two instances are considered “equal ” or “equivalent” in
value, for some appropriate meaning of “equal ”, as defined by the type’s designer.
Choosing Between Classes and Structures
You can use both classes and structures to define custom data types to use as the
bui lding blocks of your program’s code.
However, structure instances are always passed by value, and class instances are always
passed by reference. Thi s means that they are sui ted to di fferent kinds of tasks. As you
consider the data constructs and functional i ty that you need for a project, decide whether
each data construct should be defined as a class or as a structure.
As a general guidel ine, consider creating a structure when one or more of these
condi tions apply:
Examples of good candidates for structures include:
In al l other cases, define a class, and create instances of that class to be managed and
passed by reference. In practi ce, thi s means that most custom data constructs should be
classes, not structures.
Assignment and Copy Behavior for Collection Types
Swi ft’s Array and Di cti onary types are implemented as structures. However, arrays have
sl ightly di fferent copying behavior from di ctionaries and other structures when they are
The structure’s primary purpose i s to encapsulate a few relatively simple data
values.
It i s reasonable to expect that the encapsulated values wi l l be copied rather than
referenced when you assign or pass around an instance of that structure.
Any properties stored by the structure are themselves value types, whi ch would
al so be expected to be copied rather than referenced.
The structure does not need to inheri t properties or behavior from another
exi sting type.
The si ze of a geometri c shape, perhaps encapsulating a w i dth property and a hei ght
property, both of type Doubl e.
A way to refer to ranges wi thin a series, perhaps encapsulating a start property and
a l ength property, both of type Int.
A point in a 3D coordinate system, perhaps encapsulating x, y and z properties,
each of type Doubl e.
assigned to a constant or variable, and when they are passed to a function or method.
The behavior described for Array and Di cti onary below i s di fferent again from the behavior of
NSArray and NSDi cti onary in Foundation, whi ch are implemented as classes, not structures.
NSArray and NSDi cti onary instances are always assigned and passed around as a reference to
an exi sting instance, rather than as a copy.
N O T E
T he descri pti ons bel ow refer to the “copyi ng” of arrays, di cti onari es, stri ngs, and other val ues. Where copyi ng
i s menti oned, the behavi or you see i n your code w i l l al w ays be as i f a copy took pl ace. How ever, Sw i ft onl y
performs an actual copy behi nd the scenes w hen i t i s absol utel y necessary to do so. Sw i ft manages al l val ue
copyi ng to ensure opti mal performance, and you shoul d not avoi d assi gnment to try to preempt thi s
opti mi zati on.
Assignment and Copy Behavior for Dictionaries
Whenever you assign a Di cti onary instance to a constant or variable, or pass a Di cti onary
instance as an argument to a function or method cal l , the di ctionary i s copied at the point
that the assignment or cal l takes place. Thi s process i s described in Structures and
Enumerations Are Value Types.
If the keys and/or values stored in the Di cti onary instance are value types (structures or
enumerations), they too are copied when the assignment or cal l takes place. Conversely,
i f the keys and/or values are reference types (classes or functions), the references are
copied, but not the class instances or functions that they refer to. Thi s copy behavior for a
di ctionary’s keys and values i s the same as the copy behavior for a structure’s stored
properties when the structure i s copied.
The example below defines a di ctionary cal led ages, whi ch stores the names and ages of
four people. The ages di ctionary i s then assigned to a new variable cal led copi edAges and i s
copied when thi s assignment takes place. After the assignment, ages and copi edAges are two
separate di ctionaries.
var ages = ["Peter": 23, "Wei ": 35, "Ani sh": 65, "Katya": 19]
var copi edAges = ages
The keys for thi s di ctionary are of type Stri ng, and the values are of type Int. Both types are
value types in Swi ft, and so the keys and values are al so copied when the di ctionary copy
takes place.
You can prove that the ages di ctionary has been copied by changing an age value in one of
the di ctionaries and checking the corresponding value in the other. If you set the value
for "Peter" in the copi edAges di ctionary to 24, the ages di ctionary sti l l returns the old value of 23
from before the copy took place:
copi edAges["Peter"] = 24
pri ntl n(ages["Peter"])
// pri nts "23"
Assignment and Copy Behavior for Arrays
The assignment and copy behavior for Swi ft’s Array type i s more complex than for i ts
Di cti onary type. Array provides C-l ike performance when you work wi th an array’s contents
and copies an array’s contents only when copying i s necessary.
If you assign an Array instance to a constant or variable, or pass an Array instance as an
argument to a function or method cal l , the contents of the array are not copied at the
point that the assignment or cal l takes place. Instead, both arrays share the same
sequence of element values. When you modi fy an element value through one array, the
resul t i s observable through the other.
For arrays, copying only takes place when you perform an action that has the potential to
modi fy the length of the array. Thi s includes appending, inserting, or removing i tems, or
using a ranged subscript to replace a range of i tems in the array. If and when array
copying does take place, the copy behavior for an array’s contents i s the same as for a
di ctionary’s keys and values, as described in Assignment and Copy Behavior for
Di ctionaries.
The example below assigns a new array of Int values to a variable cal led a. Thi s array i s
al so assigned to two further variables cal led b and c:
var a = [1, 2, 3]
var b = a
var c = a
You can retrieve the fi rst value in the array wi th subscript syntax on ei ther a, b, or c:
pri ntl n(a[0])
// 1
pri ntl n(b[0])
// 1
pri ntl n(c[0])
// 1
If you set an i tem in the array to a new value wi th subscript syntax, al l three of a, b, and c
wi l l return the new value. Note that the array i s not copied when you set a new value
wi th subscript syntax, because setting a single value wi th subscript syntax does not have
the potential to change the array’s length:
a[0] = 42
pri ntl n(a[0])
// 42
pri ntl n(b[0])
// 42
pri ntl n(c[0])
// 42
However, i f you append a new i tem to a, you do modi fy the array’s length. Thi s prompts
Swi ft to create a new copy of the array at the point that you append the new value.
Henceforth, a i s a separate, independent copy of the array.
If you change a value in a after the copy i s made, a wi l l return a di fferent value from b and
c, whi ch both sti l l reference the original array contents from before the copy took place:
a. append(4)
a[0] = 777
pri ntl n(a[0])
// 777
pri ntl n(b[0])
// 42
pri ntl n(c[0])
// 42
Ensuring That an Array Is Unique
It can be useful to ensure that you have a unique copy of an array before performing an
action on that array’s contents, or before passing that array to a function or method. You
ensure the uniqueness of an array reference by cal l ing the unshare method on a variable of
array type. (The unshare method cannot be cal led on a constant array.)
If mul tiple variables currently refer to the same array, and you cal l the unshare method on
one of those variables, the array i s copied, so that the variable has i ts own independent
copy of the array. However, no copying takes place i f the variable i s al ready the only
reference to the array.
At the end of the previous example, b and c both reference the same array. Cal l the unshare
method on b to make i t become a unique copy:
b. unshare()
If you change the fi rst value in b after cal l ing the unshare method, al l three arrays wi l l now
report a di fferent value:
b[0] = -105
pri ntl n(a[0])
// 777
pri ntl n(b[0])
// -105
pri ntl n(c[0])
// 42
Checking Whether Two Arrays Share the Same Elements
Check whether two arrays or subarrays share the same storage and elements by
comparing them wi th the identi ty operators (=== and ! ==).
The example below uses the “identi cal to” operator (===) to check whether b and c sti l l
share the same array elements:
i f b === c {
pri ntl n("b and c sti l l share the same array el ements. ")
} el se {
pri ntl n("b and c now refer to tw o i ndependent sets of array el ements. ")
}
// pri nts "b and c now refer to tw o i ndependent sets of array el ements. "
Al ternatively, use the identi ty operators to check whether two subarrays share the same
elements. The example below compares two identi cal subarrays from b and confi rms that
they refer to the same elements:
i f b[0. . . 1] === b[0. . . 1] {
pri ntl n("T hese tw o subarrays share the same el ements. ")
} el se {
pri ntl n("T hese tw o subarrays do not share the same el ements. ")
}
// pri nts "T hese tw o subarrays share the same el ements. "
Forcing a Copy of an Array
Force an expl i ci t copy of an array by cal l ing the array’s copy method. Thi s method
performs a shal low copy of the array and returns a new array containing the copied
i tems.
The example below defines an array cal led names, whi ch stores the names of seven
people. A new variable cal led copi edNames i s set to the resul t of cal l ing the copy method on
the names array:
var names = ["Mohsen", "Hi l ary", "Justyn", "Amy", "Ri ch", "Graham", "Vi c"]
var copi edNames = names. copy()
You can prove that the names array has been copied by changing an i tem in one of the
arrays and checking the corresponding i tem in the other. If you set the fi rst i tem in the
copi edNames array to "Mo" rather than "Mohsen", the names array sti l l returns the old value of
"Mohsen" from before the copy took place:
copi edNames[0] = "Mo"
pri ntl n(names[0])
// pri nts "Mohsen"
N O T E
If you si mpl y need to be sure that your reference to an array’s contents i s the onl y reference i n exi stence,
cal l the unshare method, not the copy method. T he unshare method does not make a copy of the array
unl ess i t i s necessary to do so. T he copy method al w ays copi es the array, even i f i t i s al ready unshared.
// 이곳에 구조체를 정의하십시오
}
```
>NOTE
>새로운 클래스나 구조체를 정의할때 유용한 형이름을 주십시오. 일괄성을 스위프트 타입 표준인 UpperCamelCase를 사용하십시오(ex: SomeClass, SomeStruture).
>프로퍼티나 메소드를 정의할때는 형이름과 차별화를 주기위해 lowerCamelCase를 사용하십시오(ex: frameRate, incrementCount)

클래스와 구조체 정의문의 예:
```
struct Resolution {
var width = 0
var height = 0
}

class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
```
위의 예제는 픽셀기반 해상도를 정의하기 위한 Resolution이란 새로운 구조체를 정의합니다. 이 구조체는 width와 height라는 두개의 프로퍼티를 가지고 있습니다. 저장된 프로퍼티는 변수나 상수로서 이 클래스나 구조체의 속하며 구조체의 부분으로서 존재합니다.
이 두 프로퍼티는 정수값 0으로 초기화됨으로써 정수형입니다.

위의 예제는 또한 특정 비디오 모드를 정의하는 VideoMode라 불리는 클래스를 정의합니다. 이 클래스는 네개의 변수 저장 프로퍼티를 가지고 있습니다. 첫번째 변수인 resolution은 새로운 Resolution 구조체의 인스턴스로 초기화됩니다. 새로 생성되는 VideoMode 인스턴스는 interlaced변수는 false로 플레이 프레임 레이트는 0.0로, name은 옵션널(?) String으로 초기화합니다. name 프로퍼티는 옵셔널이기 때문에 자동적으로 기본값 nil이나 "no name value" 값을 가지게 됩니다.

## 클래스와 구조체 인스턴스
Resolution 구조체와 VideoMode 클래스는 Resolution또는 VideoMode가 어떻게 보일지를 정의할뿐 특정 해상도나 비디오모드를 정의하진 않습니다. 그렇게학 위해서 여러분은 이 구조체나 클래스의 인스턴스를 생성해야 합니다.
구조체나 클래스 인스턴스를 생성하기 위한 문법적 구조는 유사합니다.
```
let someResolution = Resolution()
let someVideoMode = VideoMode()
```
구조체와 클래스는 새 인스턴스를 생성하기위해 초기화 문법을 사용합니다. 가장 간단한 초기화 문법은 Resolution()이나 VideoMode()와 같이 클래스나 구조체의 형 이름에 괄호(())를 덧붙여주는것 입니다. 이 구문은 프로퍼티의 기본값을 갔는 새 인스턴스를 생성합니다. 자세한 클래스와 구조체의 초기화는 Initialization 항목을 참조하십시오.

## 프로퍼티 접근하기
dot(.) 문법을 사용해서 여러분은 인스턴스의 프로퍼티에 접근할수 있습니다. dot 문법은 인스턴스 이름 뒤에 공백문자 없이 dot(.)과 프로퍼티 네임을 적는것입니다.
```
println("The width of someResolution is \
(someResolution.width)")
// "The width of soneResolution is 0" 출력
```
이 예제에서 `someResolution.width`는 `someResolution`의 `width` 프로퍼티를 참조하고 기본 초기값 0를 반환합니다.
여러분은 섭(sub)프로퍼티에를 통해 `VideoMode`에 속한 `resolution` 프로퍼티의 `width` 프로퍼티에도 접근할수 있습니다.

chapter14
# 14 서브 스크립트

Write here... Class, Structures, 그리고 enumeratione의 경우 subscripts을 통해서 정의할 수 있습니다.
subscripts는 collection, list, sequence의 memberelements에 접근하기 위한 일종의 바로가기입니다. 또한 subscirpts를 사용하면 추가적인 method들을 사용하지 않고도 값을 지정하거나 검색할 수 있습니다. 예를들어서 someArray[index] 나 someDictionary[key]를 사용하여 값에 접근할 수 있습니다.

한 타입을 위해서 여러개의 subscript를 선언할 수도 있고, 또한 적절한 subscript overload의 사용은 subscript로 넘기는 index value의 type을 기본으로 하여 선택된다.
subscripts는 1차원에 제한되지 않고, 당신의 원하는 타입 형태에 따라서 다수의 input parameter를 가진 subscripts를 선언할 수 있습니다.

Subscript 문법
Subscripts는 당신이 instance의 이름 뒤에 한개 혹은 그 이상의 '[ ]'를 통해서 instance의 타입을 요청을 할수 있게 해줍니다. 그들의 문법은 instance method와 computed property의 문법과 유사합니다. subscript 선언들은 instance method와 유사하게 subscript 키워드와 특정한 하나 혹은 그 이상의 input parameter들과 return type으로 구성됩니다. 다만 instance method들과 달리 subscripts는 read-write이거나 read-only입니다.

다음 behavior는 subscript가 computed property들과 동일한 방식으로 getter와 setter를 통해 커뮤니케이션 하는 것을 보여줍니다.
/////
subscript(index: Int) -> Int {
get {
// return an appropriate subscript value here
}
set(newValue) {
// perform a suitable setting action here
}
}
/////
newValue의 type은 해당 subscript의 return 값과 동일합니다.
computed properties와 같이 당신은 setter의 parameter인 (newValue)를 특정하게 선택할수 없습니다. 만일 당신이 setter를 위한 타입을 아무것도 제공하지 않는다면, 그제서야 기본 parameter인 newValue가 setter를 위해 제공될 것입니다.

read-only computed properties와 같이 get 키워드를 빼서 read-only subscript를 만들 수 있다.:
/////
subscript(index: Int) -> Int {
// return an appropriate subscript value here
}
////
이곳에 정수의 n 배 표현을 하려는 TimesTable structure를 선언하기 을 위한 read-only subscript구현 예제가 하나 있습니다.
/////
struct TimesTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
println("six times three is \(threeTimesTable[6])")
// prints "six times three is 18"
/////
이 예제에서 새로운 TimesTable instance는 3의 배수를 출력을 하도록 생성되고.
이것은 넘겨준 값인 3을 structure의 initializer가 instance의 multiplier parameter로 사용한 것을 의미합니다.
해당 subscript를 call하는 것으로 threeTimesTable instance 에게 요청할 수 있다.보는바와같이 threeTimesTable[6]과 같이 call하는 것으로 threeTimesTable instance의 subscript를 call할 수 있다. 해당 요청은 6의 3배 테이블을 요청했으며 그 값은 18=6*3 이 된다.

NOTE
n배 테이블은 고정된 숫자값을 출력하는 규칙에 기반합니다. 따라서 newValue등을 통하여 treeTimesTable[someindex]를 설정하는 것은 적절하지 않으며 그러기에 위의 TimesTable을 위한 subscript는 read-only subscript로 선언되었습니다.

Subscript Usage

아주 정확한 의미의 "subscript"는 그것이 사용되는 문맥에 따라 결정된다. Subscripts는 일반적으로 collection, list, 또는 sequence에 특정 member elements에 접근하기 위한 바로가기라는 의미로 사용되며. 당신은 당신의 particular class나 structure의기능을 위해 대부분의 적절한 방식으로 자유롭게 subscripts를 구현할 수있다.
예를 들어서 Swift의 Dictionary type은 Dictionary instance에 저장된 값들을 설정하고 retrieve하기 위한 하나의 subscript로 구현했다.
당신은 dictionary안에 dictionary의 key 타입의 key값을 subscript의 brace안에 넣는 것으로 값을 세팅할 수 있으며 dictionary안에 들어갈 값을 subscript에 할당할 수도 있다.
You can set a value in a dictionary by providing a key of the
dictionary’s key type within subscript braces, and assigning a value of the dictionary’s
value type to the subscript:
/////
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
/////
위 예제는 numberOfLegs라는 변수를 선언하고 이를 3가지 key-value 쌍을 가진 dictionary literal로 초기화 하고있다.
numberOfLegs dictionary의 타입은 Dictionary를 뜻하며. dictionary가 생성이 된 후, 이 예제는 subscript assignment을 사용하여 String key "bird"와 int 값인 2를 dictionary에 추가하는 것을 볼 수있다.
Dictionary subscripting에 관한 보다 많은 정보를 원한다면, Accessing and Modifying a Dicionary(link)를 참고하기 바란다.

NOTE
Swift의 Dictionary type은 내부적인 key-value subscripting 이 요구하고 반환하는 타입이 optional type인 subscript로 구현하였습니다. 위의 numberOfLegs dictionary를 보면, key-value subscript 요구하고 반환하는 타입이 Int일까요?, 그렇지 않으면 “optional int”일까요? Dictionary type은 '모든 키가 값을 가지는 것은 아니다'라는 사실을 위한 모델을 지원하는 optional subscript type을 사용합니다. 그리고 어떤 key에 value를 삭제하는 방법을 제공하는데, 이경우 해당 key값의 value는 nill로 할당된다.

Subscript Options

Subscripts은 어떠한 숫자의 input parameter들도 처리가 가능하다.그리고 그리고 이 input parameter들은 어떠한 타입도 가능하다. Subscripts는 또한 어떠한 타입으로도 return이 가능하다. Subscripts는 variable parameters와 variadic parameters도 가능하지만, in-out parameters 나 default parameter 값은 지원하지 않습니다.
class나 structure는 필요한 만큼의 subscript를 구현하는 것이 가능하며, 적절한 subscript는 보통각 subscript가 사용되는 요소요소에서 subscript에 포함된이 서로 대비하도록 한 값이나 값들의 타입이 기초라고 생각할 수 있습니다.
이러한 다수의 subscripts에 관한 정의는 subscript overloading으로도 알려져 있습니다.
대부분의 한개의 parameter만을 요구하는 subscript와는 다르게, 만일 네가 만들 것에 필요하다면, 다수의 parameter를 요구하는 subscript를 선언할 수도 있습니다.
다음 예제는 Double값을 가지는 2차원 matrix를 표현하는 Matrix라는 structure를 선언하고 있습니다. Matrix structure의 subscript는 두개의 integer parameter를 요구 하고 있습니다:
/////
struct Matrix {
let rows: Int, columns: Int
var grid: Double[]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
grid = Array(count: rows * columns, repeatedValue: 0.0)
}
func indexIsValidForRow(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
subscript(row: Int, column: Int) -> Double {
get {
assert(indexIsValidForRow(row, column: column), "Index out of range")
return grid[(row * columns) + column]
}
set {
assert(indexIsValidForRow(row, column: column), "Index out of range")
grid[(row * columns) + column] = newValue
}
/////
Matrix는 rows 와 columns이라는 두개의 parameter를 요구하는 initializer 를 제공하며, Double type의 충분이 커서 rows * columns 만큼의 저장이 가능한 array를 생성합니다. 각 Matrix의 위치의 초기값은 0.0으로 주어지며. 이러한 작업이 모두 이루어 진 다음에는 만들어진 array를 array의 initializer로 보내서 올바른 크기의 array를 만듭니다. 이 initializer에 다한 자세한 사항은 Creating and Initializing an Array(링크)를 참고하세요.

이제 다음과 같은 방식으로 적절한 row와 column을 initializer에 넘기는 것으로 new Matrix instance를 생성할 수 있습니다.
/////
var matrix = Matrix(rows: 2, columns: 2)
/////
아래의 예제는 2x2의 크기를 가진 새로운 Matrix instance를 생성하는 예제입니다. matrix instace를 효과적으로 평평하게 펴서 보여주기 위한 grid array를 참고하면 왼쪽위에서부터 오른쪽 아래로 읽어 나가는 것을 볼 수 있습니다.
/////
(그림있음)
/////
matrix의 값을 넣을때는 ,를 이용해서 subscript에 맞는 형태로 값을 넘겨주면 세팅할 수 있습니다:
////
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2
/////
이 두 문장은 우측 상단의 값([0, 1])을 1.5로, 좌측 하단의 값([1, 0])을 3.2로 설정합니다:
/////
(그림있음)
/////
Matrix의 subscript의 getter와 setter는 모두 올바른 row와 column값이 들어오는지 체크하는 assertion을 포함하고 있습니다. 이 assertion들을 돕기 위하여 Matrix는 자체적으로 indexIsValid라는 convenience method를 가지고 있으며 이는 주어진 값이 matrix의 범위를 넘어가는지 아닌지를 체크합니다:
func indexIsValidForRow(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
만일 matrix의 경계를 넘어가는 값이 subscript로 들어오게 된다면 assertion이 triggered됩니다:
let someValue = matrix[2, 2]
// this triggers an assert, because [2, 2] is outside of the matrix bounds



chapter15
# chapter1515 상속

Write here...

chapter16
# 16 상속초기화

Write here...
chapter17
# 17 초기화

Write here..
해제(Deinitialization)

deinitializer 는 임의의 class 인스턴스가 할당해제(deallocate) 되기 직전에 호출된다. initializer를 init 키워드 안에 기술했던 것처럼, deinitializer는 deinit 키워드 안에 적어 넣는다. deinitializer는 class 타입 인스턴스에서만 사용할 수 있다.

## Deinitialization (해제)의 원리

Swift에서는 더 이상 사용되지 않는 인스턴스는 자동으로 할당해제 된다. 이는 Automatic Reference Counting에서 설명한 바와 같이 ARC를 통해 이루어지는데, 일반적인 경우 사용자가 직접 메모리 사용을 할당해제할 필요가 없다. 하지만, 사용자의 인스턴스에서 직접 리소스를 할당하여 사용했다면, 해제할 때도 직접 해제해 주어야 한다. 가령, 사용자의 인스턴스에서 파일을 열어서 사용했다면, 해제할 때, 직접 파일을 닫아주어야 한다. class마다 오직 한 개의 deinitializer만을 사용할 수 있으며, 파라미터 없이 정의한다.

deinit {
// perform the deinitialization
}

deinitializer는 할당해제(deallocation)가 일어나기 직전에 자동으로 호출되기 때문에, 사용자가 직접 호출하는 것을 허용하지 않는다. subclass는 superclass의 deinitializer를 상속받기 때문에, subclass의 deinitializer가 호출되어 작업을 마친 후, superclass의 deinitializer가 자동으로 호출된다. superclass의 deinitializer는 subclass의 deinitializer가 정의되지 않았더라도 항상 호출된다. deinitializer가 아직 호출되지 않은 인스턴스는 해제(deallocation)가 되지 않은 상태이고, deinitializer는 자신이 속한 인스턴스의 모든 속성(가령, 닫아야할 파일의 이름과 상태)을 변경할 수 있다.

## Deinitializer 사용 예

deinitializer를 사용하는 간단한 예를 들어보자. 간단한 게임을 만들기 위해, Bank와 Player 라는 두개의 데이터 타입을 정의하기로 하자. Bank는 화폐를 만드는데, 최대 10,000개의 동전을 유통할 수 있다. 게임에서는 오직 한 개의 Bank만 있다고 가정, Bank는 static으로 구현되었다.

struct Bank {
static var coinsInBank = 10000
static func vendCoins(var numberOfCoinsToVend: Int) -> Int {
numberOfCoinsToVend = min(numberOfCoinsToVend, coinsInBank)
coinsInBank -= numberOfCoinsToVend
return numberOfCoinsToVend
}
static func receiveCoins(coins: Int) {
coinsInBank += coins
}

Bank클래스는 coinsInBank속성으로 현 상태의 동전 수를 유지한다. vendCoins과 receiveCoins 메소드는 동전을 인출하거나 예치할 때 사용한다.

vendCoins 메소드는 은행에 동전이 남아 있는지 확인하고 Player에게 인출을 허용한다. Player 가 요청한 것보다 동전이 적게 남아 있으면, 남아 있는 만큼만 인출할 수 있다. (물론 은행에 동전이 전혀 없다면, ‘0’ 를 리턴한다). numberOfCoinsToVend 변수는 파라미터로 입력받아 변경이 가능하게 만들었다. receiveCoins메소드는 단순히 Player가 예치하는 동전을 은행에 더해서 쌓도록 되어 있다.

Player 클래스를 보면, coinsInPurse 속성에 게임 플레이어가 현재 보유한 동전을 기록한다.

class Player {
var coinsInPurse: Int
init(coins: Int) {
coinsInPurse = Bank.vendCoins(coins)
}
func winCoins(coins: Int) {
coinsInPurse += Bank.vendCoins(coins)
}
deinit {
Bank.receiveCoins(coinsInPurse)
}
}

Player인스턴스는 은행으로부터 어느 정도의 동전을 받으면서 초기화된다. 경우에 따라서 은행에 충분한 코인이 남아 있지 않다면 요청한 만큼의 동전보다 적게 받을 수도 있다. winCoins 메소드는 은행에서 (coins : Int) 만큼의 동전을 받아 Player의 지갑에 더해 준다. Player클래스에는 deinitializer 가 정의되어 있는데, 앞서 설명한 바 처럼 Player 인스턴스가 해제(deallocate)되기 직전에 호출된다. 여기서는 단순히 플레이어가 가진 모든 동전을 다시 은행에 리턴하는 역할을 한다.


var playerOne: Player? = Player(coins: 100)
println("A new player has joined the game with \(playerOne!.coinsInPurse) coins")
// prints "A new player has joined the game with 100 coins"
println("There are now \(Bank.coinsInBank) coins left in the bank")
// prints "There are now 9900 coins left in the bank"


--> 요기서 부터 다시 재개


A new Player instance is created, with a request for 100 coins if they are available. This Player instance is stored in an optional Player variable called playerOne. An optional variable is used here, because players can leave the game at any point. The optional lets you track whether there is currently a player in the game.
Because playerOne is an optional, it is qualified with an exclamation mark (!) when its coinsInPurse property is accessed to print its default number of coins, and whenever its winCoins method is called:

playerOne!.winCoins(2000)
println("PlayerOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins")
// prints "PlayerOne won 2000 coins & now has 2100 coins"
println("The bank now only has \(Bank.coinsInBank) coins left")
// prints "The bank now only has 7900 coins left"

Here, the player has won 2,000 coins. The player’s purse now contains 2,100 coins, and the bank has only 7,900 coins left.

playerOne = nil
println("PlayerOne has left the game")
// prints "PlayerOne has left the game"
println("The bank now has \(Bank.coinsInBank) coins")
// prints "The bank now has 10000 coins"

The player has now left the game. This is indicated by setting the optional playerOne variable to nil, meaning “no Player instance.” At the point that this happens, the playerOne variable’s reference to the Player instance is broken. No other properties or variables are still referring to the Player instance, and so it is deallocated in order to free up its memory.
Just before this happens, its deinitializer is called automatically, and its coins are returned to the bank
.
chapter18
# 18 해제(Deinitialization)자동 참조 계수

Write here...
chapter19
# 19 자동 참조 계수옵션 연쇄 (Optional Chaining)


Write here...
chapter2
# 02 Swift 둘러보기


Write here...
새로운 언어를 배울 때 첫번째 프로그램은 전통적으로 화면에 "Hello, world"란 구문을 출력해 보는 것입니다. Swift에서는 단 한줄로 이것이 가능합니다.

println("Hello, world")

C나 Objective-C에서 코드를 작성해본적이 있다면 Swift에서 이 한줄의 코드가 완전한 프로그램을 구성하는 이런 문법이 매우 익숙할 것입니다. 입.출력이나 문자열을 다루기 위한 함수들 같은 기능들을 위한 분리된 라이브러리를 임포트할 필요가 없습니다. 프로그램의 전체 지점에 있어서 코드는 전역 범위(Global scope)로 쓰여지고, 때문에 main 함수는 필요하지 않습니다. 또한 모든 문장끝에 세미콜론을 쓸 필요도 없습니다.

이 둘러보기는 다양한 프로그래밍 과제를 어떻게 완수해 나가는지 보여주면서 Swift로 어떻게 코드를 작성해야하는지에 대한 충분한 정보를 제공할 것입니다. 몇몇가지를 이해하지 못한다고 해서 걱정하지 마세요. 이번 장에서 소개되는 모든 것들은 책의 뒷 부분에서 자세히 설명될 것입니다.

`노트
최선의 경험을 위해서 이번 장을 Xcode안에서 playground로 열어보세요. Playground는 코드의 수정과 즉시 결과를 볼 수 있도록 해줄 것입니다.

##간단한 값

let을 사용하면 상수를 만들고 var를 사용하면 변수를 만들 수 있습니다. 상수는 컴파일 타임에 알고 있을 필요가 없습니다. 그러나 오직 한번만 값을 할당해야합니다. 이것은 상수를 값을 한번만 결정하고 여러곳에 쓰일 이름으로 사용할 수 있다는 것을 의미합니다.

1| var myVariable =42
2| myVariable = 50
3| let myConstant = 42

상수나 변수 모두 당신이 할당하고 싶은 값의 타입을 가질 수 있습니다. 그러나 항상 타입을 명시해야만 하는 것은 아닙니다. 당신이 상수나 변수를 만들 때 할당한 값을 통해 컴파일러는 그 값의 타입을 추측합니다. 위의 예를 보면, myVariable이 정수형 값으로 초기화되었기 때문에 컴파일러는 정수형이라고 추측합니다.

만약 초기값이 충분한 정보를 제공하지 못한 경우(혹은 초기값이 없는 경우) 특정한 타입을 변수명 뒤에 세미콜론으로 분리하여 써주어야 합니다.

1| let inplicitInteger = 70
2| let implicitDouble = 70.0
3| let explicitDouble: Double = 70

`실험
4와 명시적으로 Float 형태의 값을 갖는 상수를 만들어보자.

값은 절대 암시적으로 다른 형태의 값으로 변환할 수 없습니다. 만약 다른 형태의 값으로 변화해야 한다면 명시적으로 원하는 형태의 인스턴스로 만들어야 합니다.

1| let label = "The width is "
2| let width = 94
3| let widthLabel = label + String(width)

`실험
마지막줄에 있는 String으로 변환 부분을 제거해보자. 어떤 에러가 발생하는가?

문자열 안에 값들을 포함하는 쉬운 방법도 있습니다. 괄호 안에 값을 쓰고 괄호 앞에 백슬래시를 쓰면 됩니다. 예를 들면

1| let apples = 3
2| let oranges = 5
3| let appleSummary = "I have \(apples) apples."
4| let fruitSummary = "I have \(apples + oranges) pieces of fruit."

`실험
문자열안에 \()를 이용해 실수형 계산을 포함하도록 해보고, 인사말 안에 누군가의 이름을 넣어보자.

배열과 딕셔너리는 대괄호([])를 이용해 만들 수 있습니다. 그리고 대괄호 안에 인덱스나 키를 이용해 각각의 요소에 접근할 수 있습니다.

1| var shoppingList = ["catfish", "water", "tulips", "blue paint"]
2| shoppingList[1] = "bottle of water"
3|
4| var occupations = [
5| "Malcolm":"Captian",
6| "Kaylee":"Mechanic",
7| ]
8| occupations["Jayne"] = "Public Relations"

빈 배열이나 딕셔너리를 만들려면, 초기화자(initializer) 문법을 사용하면 됩니다.

1| let emptyArray = String[]()
2| let emptyDictionary = Dictionary()

타입 정보를 추론할 수 없다면 빈 배열은 []로 빈 딕셔너리는 [:]로 쓸 수 있습니다. 예를 들어 변수에 새로운 값을 할당하거나 함수에 인자로 넘겨줄 때

shoppingList = [] //쇼핑을 가서 모든 것을 샀다.

##흐름 통제
if와 switch를 사용해서 조건문을 만들 수 있고 for-in, for, while, do-while을 이용해서 반복문을 만들 수 있습니다. 조건문과 반복문을 괄호로 감싸는 것은 선택사항입니다. 중괄호로 몸통을 감싸는 것은 필수입니다.

1| let individualScores = [75, 43, 103, 87, 12]
2| var teamScore = 0
3| for score in individualScores {
4| if score > 50 {
5| teamScore += 3
6| } else {
7| teamScore += 1
8| }
9|}
10|teamScore

if문 안에 조건은 꼭 불리언(Boolean) 표현이어야 합니다. 이것은 if score {...} 이 0과의 비교를 암시하지 않기 때문에 에러가 발생합니다.

사라질 값을 가지고 if와 let을 함께 사용하는 것도 가능합니다. 이런 값들은 옵션으로 대표됩니다. 옵션값은 어떤 값을 가지거나 사라질 값을 표현하는 nil을 가지기도 합니다. 값의 타입 뒤에 물음표를 쓰면 옵션값이라는 것을 나타냅니다.

1| var optionalString: String? = "Hello"
2| optionalString == nil
3|
4| var optionalName: String? = "John Appleseed"
5| var greeting = "Hello!"
6| if let name = optionalName {
7| greeting = "Hello, \(name)"
8| }

`실험
optionalName의 값을 nil로 바꿔보자. 어떤 greeting의 값을 받을 수 있는가? optionalName이 nil일 때 다른 값을 greeting에 할당하도록 else 절을 추가해보자.

만약 옵션값이 nil이라면 조건문은 false이고 중괄호 안에 있는 코드를 건너뛰게 됩니다. 반대의 경우에는 중괄호 블록 안에서 사용할 수 있도록 let 뒷부분의 상수에 값이 할당되고 옵션값으로 사용할 수 있습니다.

스위치(Switch) 구문에는 정수형 값이나 동등 비교연산 뿐만 아니라 어떤 종류의 데이터든 사용할 수 있고 다양한 비교 연산자들을 사용할 수 있습니다.

1| let vegetable = "red pepper"
2| switch vegetable {
3| case "celery":
4| let vegetableComment = "Add some raisins and make ants on a log."
5| case "cucumber", "watercress":
6| let vegetableComment = "That would make a good tea sandwich."
7| case let x where x.hasSuffix("pepper"):
8| let vegetableComment = "Is it a spicy \(x)?"
9| default:
10| let vegetableComment = "Everything tastes good in soup."
11| }

실험
스위치 구문에서 default의 경우를 제거해 보자. 어떤 에러가 발생하는가?

스위치 구문안의 일치하는 경우의 코드를 실행하고 나면 프로그램은 스위치 구문을 빠져나옵니다. 실행한 코드 이후에 나오는 내용은 실행하지 않기 때문에 각 경우의 코드 끝마다 빠져나오도록 명시적으로 써주지 않아도됩니다.(*역자 주: 보통 사용되는 break를 굳이 쓸 필요가 없다는 것입니다.)

for-in 문을 사용하면 각각 키-값 쌍으로 사용할 수 있는 이름들의 쌍을 이용해 딕셔너리에 있는 요소들을 반복처리할 수 있습니다.

1| let interestingNumbers = [
2| "Prime": [2, 3, 5, 7, 11, 13],
3| "Fibonacci": [1, 1, 2, 3, 5, 8],
4| "Square": [1, 4, 9, 16, 25],
5| ]
6| var largest = 0
7| for (kind, numbers) in interestingNumbers {
8| for number in numbers {
9| if number > largest {
10| largest = number
11| }
12| }
13| }
14| largest

실험
계속 알아 보기 위해서 기존의 제일 큰 값만큼 큰 값을 가지는 요소를 추가해보자.

조건문이 변경될 때까지 코드 블록을 반복 실행하기 위해서 while 문을 사용해 봅시다.

반복문이 적어도 한번은 실행될 수 있도록 보장하기 위해서 조건문을 반복문 끝에 쓸수도 있습니다.

1| var n = 2
2| while n < 100 {
3| n = n * 2
4| }
5| n
6|
7| var m = 2
8| do {
9| m = m * 2
10| } while m < 100
11| m

반복문안에서 ..을 사용해 인덱스의 범위를 만들어 사용하거나 명시적으로 초기화, 조건문, 증감식을 사용하는 것 또한 가능합니다. 아래쪽에 나오는 두가지 반복문은 동일한 일을 수행합니다.

1| var firstForLoop = 0
2| for i in 0..3 {
3| firstForLoop += i
4| }
5| firstForLoop
6|
7| var secondForLoop = 0
8| for var i = 0; i < 3; ++i {
9| secondForLoop += 1
10| }
11| secondForLoop

..을 사용해서 범위를 지정하면 제일 나중값은 제외가 됩니다. 대신 ...을 사용하면 양쪽 끝값 모두 포함하게 됩니다.

##함수(Functions)와 클로저(Closures)

func를 사용해 함수를 선언할 수 있습니다. 함수의 이름과 괄호안에 인자들을 넣어서 함수를 호출할 수 있습니다. 매개변수들의 이름과 분리해서 ->를 사용해 타입을 써주면 함수 반환값의 타입을 지정할 수 있습니다.

1| func greet(name: String, day: String) -> String {
2| return "Hello \(name), today is \(day)."
3| }
4| greet("Bob", "Tuesday")


실험
매개변수 day를 제거하고 오늘의 스페셜 런치 매개변수를 greeting에 추가해보자.

튜플(tuple)을 사용하면 여러개의 값을 반환할 수 있습니다.

1| func getGasPrices() -> (Double, Double, Double) {
2| return (3.59, 3.69, 3.79)
3| }
4| getGasPrices()

함수는 배열을 이용해서 여러개의 값을 인자로 받는 것도 가능합니다.

1| func sumOf(numbers: Int...) -> Int {
2| var sum = 0
3| for number in numbers {
4| sum += number
5| }
6| return sum
7| }
8| sumOf()
9| sumOf(42, 597, 12)

실험
인자들의 평균값을 계산하는 함수를 만들어보자.

함수는 다른 것에 포함될 수도 있습니다. 내장된(Nested) 함수는 감싸고 있는 함수에서 선언된 변수에 접근할 수 있습니다. 길어지고 복잡한 함수의 코드를 정리하기 위해 내장된 함수를 사용할 수 있습니다.

1| func returnFifteen() -> Int {
2| var y = 10
3| func add() {
4| y += 5
5| }
6| add()
7| return y
8| }
9| returnFifteen()

함수는 최상위 타입입니다. 이것은 어떤 함수가 다른 함수를 반환값형태로 반환할 수 있다는 것을 의미합니다.

1| func makeIncrementer() -> (Int -> Int) {
2| func addOne(number: Int) -> Int {
3| return 1 + number
4| }
5| return addOne
6| }
7| var increment = makeIncrementer()
8| increment(7)

또 함수는 다른 함수를 인자로 받을 수 있습니다.

1| func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {
2| for item in list {
3| if condition(item) {
4| return true
5| }
6| }
7| return false
8| }
9| func lessThanTen(number: Int) -> Bool {
10| return number < 10
11| }
12| var numbers = [20, 19, 7, 12]
13| hasAnyMatches(numbers, lessThanTen)

함수는 실제로는 클로저의 특별한 예입니다. 중괄호로 묶기만 해서 이름없이 클로저를 사용할 수도 있습니다. in을 사용해 몸통에서 인자와 반환값 타입을 분리해 쓸 수 있습니다.

1| numbers.map({
2| (number: Int) -> Int in
3| let result = 3 * number
4| return result
5| })

실험
모든 홀수값에 대해 0을 반환하도록 클로저를 수정해보자.

클로저를 간결하게 쓰기 위한 몇가지 옵션이 있습니다. 델리게이트(delegate)를 위한 콜백같이 이미 클로저의 타입을 아는 경우라면 매개변수의 타입, 반환값 타입을 모두 생략하거나 선택적으로 생략할 수 있습니다. 한줄짜리 구문을 가진 클로저라면 구문만 가지고도 반환 타입을 추측할 수 있습니다.

numbers.map({ number in 3 * number })

매개변수의 이름 대신에 번호로 참조하는 것은 클로저를 짧게 만드는데 특히 유용합니다. 이때 클로저는 함수의 바로 뒤에 중괄호를 이용해 인자로 전달됩니다.

sort([1, 5, 3, 12, 2]) { $0 > $1 }

##객체(Objects)와 클래스(Classes)

chapter20
# 20 옵션 연쇄타입 변환

Write here...
chapter21
# 21 타입 변환

Write here..
Nested Types(중첩 형식)

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

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

## 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가지 슈트(블랙잭에서 슈트란 카드에 있는 무늬를 말합니다.)들과 슈트의 그에 해당하는**Character** 심볼 값을 함께 나타냅니다.

**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** 값을 사용합니다.

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

**BalckjacCard**구조체는 커스텀 이니셜라이저를 가지고 있지 않으므로, 앞 챕터의 [구조체 타입을 위한 멤버 단위의 이니셜라이저(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**가 **BlackjacCard**안에 중첩되어 있다고 해도 그들의 타입은 문맥으로 부터 추론될 수 았가 때문에 이 인스턴스의 초기화는 자신의 맴버 이름(.Ace와 .Spades)으로 열거형 멤버를 참조할 수 있습니다. 위의 예에서는 **description**속성이 올바르게 Space Ace 카드가 1 또는 11의 값을 가지고 있는지 확인합니다.

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

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

위의 예를 보면, 그들의 이름은 자연스럽게 그들이 정의된 문맥에 의해 규정되기 때문에 **Suit, Rank, Values**의 이름이 의도적으로 짧게 할 수 있습니다
.
chapter22
# 22 내부 타입확장

Write here...
chapter23
# 23 확장

Write here...
프로토콜

# 23 Protocols
A protocol defines a blueprint of methods, properties, and other requirements that suit a
particular task or piece of functionality. The protocol doesn’t actually provide an
implementation for any of these requirements—it only describes what an implementation
will look like. The protocol can then be adopted by a class, structure, or enumeration to
provide an actual implementation of those requirements. Any type that satisfies the
requirements of a protocol is said to conform to that protocol.
프로토콜은 특정 작업이나 기능에 부합하는 메소드, 속성, 그리고 다른 요구사항들에 대한 청사진과 같습니다. 프로토콜에는 이런 요구사항들에 대한 어떤 구현도 포함하지 않고, 다만 구현된 모습이 어떨지 윤곽만 드러납니다. 그러면 클래스, 구조체나 열거형에서 프로토콜을 따라 요구사항들을 실제로 구현하게 됩니다. 프로토콜의 요구사항을 만족하는 형(`type`)이라면 그 프로토콜에 들어맞다(conform)라고 하죠.

Protocols can require that conforming types have specific instance properties, instance
methods, type methods, operators, and subscripts.
Protocol Syntax
You define protocols in a very similar way to classes, structures, and enumerations:
protocol SomeProtocol {
// protocol definition goes here
}
Custom types state that they adopt a particular protocol by placing the protocol’s name
after the type’s name, separated by a colon, as part of their definition. Multiple protocols
can be listed, and are separated by commas:
struct SomeStructure: FirstProtocol, AnotherProtocol {
// structure definition goes here
}
If a class has a superclass, list the superclass name before any protocols it adopts,
followed by a comma:
class SomeClass: SomeSuperclass, FirstProtocol, AnotherProtocol {
// class definition goes here
}
Property Requirements
A protocol can require any conforming type to provide an instance property or type
property with a particular name and type. The protocol doesn’t specify whether the
property should be a stored property or a computed property—it only specifies the
required property name and type. The protocol also specifies whether each property must
be gettable or gettable and settable.
If a protocol requires a property to be gettable and settable, that property requirement
cannot be fulfilled by a constant stored property or a read-only computed property. If the
protocol only requires a property to be gettable, the requirement can be satisfied by any
kind of property, and it is valid for it also to be settable if this is useful for your own code.
Property requirements are always declared as variable properties, prefixed with the var
keyword. Gettable and settable properties are indicated by writing { get set } after their
type declaration, and gettable properties are indicated by writing { get }.
protocol SomeProtocol {
var mustBeSettable: Int { get set }
var doesNotNeedToBeSettable: Int { get }
}
Always prefix type property requirements with the class keyword when you define them in
a protocol. This is true even though type property requirements are prefixed with the static
keyword when implemented by a structure or enumeration:
protocol AnotherProtocol {
class var someTypeProperty: Int { get set }
}
Here’s an example of a protocol with a single instance property requirement:
protocol FullyNamed {
var fullName: String { get }
}
The FullyNamed protocol defines any kind of thing that has a fully-qualified name. It doesn’t
specify what kind of thing it must be—it only specifies that the thing must be able to
provide a full name for itself. It specifies this requirement by stating that any FullyNamed
type must have a gettable instance property called fullName, which is of type String.
Here’s an example of a simple structure that adopts and conforms to the FullyNamed
protocol:
struct Person: FullyNamed {
var fullName: String
}
let john = Person(fullName: "John Appleseed")
// john.fullName is "John Appleseed"
This example defines a structure called Person, which represents a specific named person.
It states that it adopts the FullyNamed protocol as part of the first line of its definition.
Each instance of Person has a single stored property called fullName, which is of type String.
This matches the single requirement of the FullyNamed protocol, and means that Person has
correctly conformed to the protocol. (Swift reports an error at compile-time if a protocol
requirement is not fulfilled.)
Here’s a more complex class, which also adopts and conforms to the FullyNamed protocol:
class Starship: FullyNamed {
var prefix: String?
var name: String
init(name: String, prefix: String? = nil) {
self.name = name
self.prefix = prefix
}
var fullName: String {
return (prefix ? prefix! + " " : "") + name
ncc1701 = Starship(name: "Enterprise", prefix: "USS")
ncc1701.fullName is "USS Enterprise"
This class implements the fullName property requirement as a computed read-only property
for a starship. Each Starship class instance stores a mandatory name and an optional prefix.
The fullName property uses the prefix value if it exists, and prepends it to the beginning of
name to create a full name for the starship.
Method Requirements
Protocols can require specific instance methods and type methods to be implemented by
conforming types. These methods are written as part of the protocol’s definition in exactly
the same way as for normal instance and type methods, but without curly braces or a
method body. Variadic parameters are allowed, subject to the same rules as for normal
methods.
N O T E
Protocols use the same syntax as normal methods, but are not allowed to specify default values for method
parameters.
As with type property requirements, you always prefix type method requirements with the
class keyword when they are defined in a protocol. This is true even though type method
requirements are prefixed with the static keyword when implemented by a structure or
enumeration:
protocol SomeProtocol {
class func someTypeMethod()
}
The following example defines a protocol with a single instance method requirement:
protocol RandomNumberGenerator {
func random() -> Double
}
This protocol, RandomNumberGenerator, requires any conforming type to have an instance
method called random, which returns a Double value whenever it is called. (Although it is not
specified as part of the protocol, it is assumed that this value will be a number between
0.0 and 1.0 inclusive.)
The RandomNumberGenerator protocol does not make any assumptions about how each random
number will be generated—it simply requires the generator to provide a standard way to
generate a new random number.
Here’s an implementation of a class that adopts and conforms to the RandomNumberGenerator
protocol. This class implements a pseudorandom number generator algorithm known as a
linear congruential generator:
class LinearCongruentialGenerator: RandomNumberGenerator {
var lastRandom = 42.0
let m = 139968.0
let a = 3877.0
let c = 29573.0
func random() -> Double {
lastRandom = ((lastRandom * a + c) % m)
return lastRandom / m
}
generator = LinearCongruentialGenerator()
("Here's a random number: \(generator.random())")
prints "Here's a random number: 0.37464991998171"
("And another one: \(generator.random())")
prints "And another one: 0.729023776863283"
Mutating Method Requirements
It is sometimes necessary for a method to modify (or mutate) the instance it belongs to.
For instance methods on value types (that is, structures and enumerations) you place the
mutating keyword before a method’s func keyword to indicate that the method is allowed to
modify the instance it belongs to and/or any properties of that instance. This process is
described in Modifying Value Types from Within Instance Methods.
If you define a protocol instance method requirement that is intended to mutate
instances of any type that adopts the protocol, mark the method with the mutating keyword
as part of the protocol’s definition. This enables structures and enumerations to adopt the
protocol and satisfy that method requirement.
N O T E
If you mark a protocol instance method requirement as mutating, you do not need to write the mutating
keyword when writing an implementation of that method for a class. The mutating keyword is only used by
structures and enumerations.
The example below defines a protocol called Togglable, which defines a single instance
method requirement called toggle. As its name suggests, the toggle method is intended to
toggle or invert the state of any conforming type, typically by modifying a property of that
type.
The toggle method is marked with the mutating keyword as part of the Togglable protocol
definition, to indicate that the method is expected to mutate the state of a conforming
instance when it is called:
protocol Togglable {
mutating func toggle()
}
If you implement the Togglable protocol for a structure or enumeration, that structure or
enumeration can conform to the protocol by providing an implementation of the toggle
method that is also marked as mutating.
The example below defines an enumeration called OnOffSwitch. This enumeration toggles
between two states, indicated by the enumeration cases On and Off. The enumeration’s
toggle implementation is marked as mutating, to match the Togglable protocol’s requirements:
enum OnOffSwitch: Togglable {
case Off, On
mutating func toggle() {
switch self {
case Off:
self = On
case On:
self = Off
}
lightSwitch = OnOffSwitch.Off
lightSwitch.toggle()
lightSwitch is now equal to .On
Protocols as Types
Protocols do not actually implement any functionality themselves. Nonetheless, any
protocol you create will become a fully-fledged type for use in your code.
Because it is a type, you can use a protocol in many places where other types are
allowed, including:
N O T E
Because protocols are types, begin their names with a capital letter (such as FullyNamed and
RandomNumberGenerator) to match the names of other types in Swift (such as Int, String, and Double).
Here’s an example of a protocol used as a type:
class Dice {
let sides: Int
let generator: RandomNumberGenerator
init(sides: Int, generator: RandomNumberGenerator) {
self.sides = sides
self.generator = generator
}
func roll() -> Int {
return Int(generator.random() * Double(sides)) + 1
This example defines a new class called Dice, which represents an n-sided dice for use in a
board game. Dice instances have an integer property called sides, which represents how
many sides they have, and a property called generator, which provides a random number
generator from which to create dice roll values.
As a parameter type or return type in a function, method, or initializer
As the type of a constant, variable, or property
As the type of items in an array, dictionary, or other container
The generator property is of type RandomNumberGenerator. Therefore, you can set it to an
instance of any type that adopts the RandomNumberGenerator protocol. Nothing else is required
of the instance you assign to this property, except that the instance must adopt the
RandomNumberGenerator protocol.
Dice also has an initializer, to set up its initial state. This initializer has a parameter called
generator, which is also of type RandomNumberGenerator. You can pass a value of any conforming
type in to this parameter when initializing a new Dice instance.
Dice provides one instance method, roll, which returns an integer value between 1 and the
number of sides on the dice. This method calls the generator’s random method to create a
new random number between 0.0 and 1.0, and uses this random number to create a dice
roll value within the correct range. Because generator is known to adopt RandomNumberGenerator,
it is guaranteed to have a random method to call.
Here’s how the Dice class can be used to create a six-sided dice with a
LinearCongruentialGenerator instance as its random number generator:
var d6 = Dice(sides: 6, generator: LinearCongruentialGenerator())
for _ in 1...5 {
println("Random dice roll is \(d6.roll())")
}
// Random dice roll is 3
// Random dice roll is 5
// Random dice roll is 4
// Random dice roll is 5
// Random dice roll is 4
Delegation
Delegation is a design pattern that enables a class or structure to hand off (or delegate)
some of its responsibilities to an instance of another type. This design pattern is
implemented by defining a protocol that encapsulates the delegated responsibilities, such
that a conforming type (known as a delegate) is guaranteed to provide the functionality
that has been delegated. Delegation can be used to respond to a particular action, or to
retrieve data from an external source without needing to know the underlying type of that
source.
The example below defines two protocols for use with dice-based board games:
protocol DiceGame {
var dice: Dice { get }
func play()
}
protocol DiceGameDelegate {
func gameDidStart(game: DiceGame)
func game(game: DiceGame, didStartNewTurnWithDiceRoll diceRoll: Int)
func gameDidEnd(game: DiceGame)
}
The DiceGame protocol is a protocol that can be adopted by any game that involves dice.
The DiceGameDelegate protocol can be adopted by any type to track the progress of a DiceGame.
Here’s a version of the Snakes and Ladders game originally introduced in Control Flow.
This version is adapted to use a Dice instance for its dice-rolls; to adopt the DiceGame
protocol; and to notify a DiceGameDelegate about its progress:
class SnakesAndLadders: DiceGame {
let finalSquare = 25
let dice = Dice(sides: 6, generator: LinearCongruentialGenerator())
var square = 0
var board: Int[]
init() {
board = Int[](count: finalSquare + 1, repeatedValue: 0)
board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
var delegate: DiceGameDelegate?
func play() {
square = 0
delegate?.gameDidStart(self)
gameLoop: while square != finalSquare {
let diceRoll = dice.roll()
delegate?.game(self, didStartNewTurnWithDiceRoll: diceRoll)
switch square + diceRoll {
case finalSquare:
break gameLoop
case let newSquare where newSquare > finalSquare:
continue gameLoop
default:
square += diceRoll
square += board[square]
}
}
delegate?.gameDidEnd(self)
For a description of the Snakes and Ladders gameplay, see the Break section of the
Control Flow chapter.
This version of the game is wrapped up as a class called SnakesAndLadders, which adopts the
DiceGame protocol. It provides a gettable dice property and a play method in order to conform
to the protocol. (The dice property is declared as a constant property because it does not
need to change after initialization, and the protocol only requires that it is gettable.)
The Snakes and Ladders game board setup takes place within the class’s init() initializer.
All game logic is moved into the protocol’s play method, which uses the protocol’s required
dice property to provide its dice roll values.
Note that the delegate property is defined as an optional DiceGameDelegate, because a delegate
isn’t required in order to play the game. Because it is of an optional type, the delegate
property is automatically set to an initial value of nil. Thereafter, the game instantiator has
the option to set the property to a suitable delegate.
DiceGameDelegate provides three methods for tracking the progress of a game. These three
methods have been incorporated into the game logic within the play method above, and
are called when a new game starts, a new turn begins, or the game ends.
Because the delegate property is an optional DiceGameDelegate, the play method uses optional
chaining each time it calls a method on the delegate. If the delegate property is nil, these
delegate calls fail gracefully and without error. If the delegate property is non-nil, the
delegate methods are called, and are passed the SnakesAndLadders instance as a parameter.
This next example shows a class called DiceGameTracker, which adopts the DiceGameDelegate
protocol:
class DiceGameTracker: DiceGameDelegate {
var numberOfTurns = 0
func gameDidStart(game: DiceGame) {
numberOfTurns = 0
if game is SnakesAndLadders {
println("Started a new game of Snakes and Ladders")
}
println("The game is using a \(game.dice.sides)-sided dice")
}
func game(game: DiceGame, didStartNewTurnWithDiceRoll diceRoll: Int) {
++numberOfTurns
println("Rolled a \(diceRoll)")
func gameDidEnd(game: DiceGame) {
println("The game lasted for \(numberOfTurns) turns")
DiceGameTracker implements all three methods required by DiceGameDelegate. It uses these
methods to keep track of the number of turns a game has taken. It resets a numberOfTurns
property to zero when the game starts; increments it each time a new turn begins; and
prints out the total number of turns once the game has ended.
The implementation of gameDidStart shown above uses the game parameter to print some
introductory information about the game that is about to be played. The game parameter
has a type of DiceGame, not SnakesAndLadders, and so gameDidStart can access and use only
methods and properties that are implemented as part of the DiceGame protocol. However,
the method is still able to use type casting to query the type of the underlying instance.
In this example, it checks whether game is actually an instance of SnakesAndLadders behind the
scenes, and prints an appropriate message if so.
gameDidStart also accesses the dice property of the passed game parameter. Because game is
known to conform to the DiceGame protocol, it is guaranteed to have a dice property, and so
the gameDidStart method is able to access and print the dice’s sides property, regardless of
what kind of game is being played.
Here’s how DiceGameTracker looks in action:
let tracker = DiceGameTracker()
let game = SnakesAndLadders()
game.delegate = tracker
game.play()
// Started a new game of Snakes and Ladders
// The game is using a 6-sided dice
// Rolled a 3
// Rolled a 5
// Rolled a 4
Rolled a 5
The game lasted for 4 turns
Adding Protocol Conformance with an Extension
You can extend an existing type to adopt and conform to a new protocol, even if you do
not have access to the source code for the existing type. Extensions can add new
properties, methods, and subscripts to an existing type, and are therefore able to add any
requirements that a protocol may demand. For more about extensions, see Extensions.
N O T E
Existing instances of a type automatically adopt and conform to a protocol when that conformance is added to
the instance’s type in an extension.
For example, this protocol, called TextRepresentable, can be implemented by any type that
has a way to be represented as text. This might be a description of itself, or a text
version of its current state:
protocol TextRepresentable {
func asText() -> String
}
The Dice class from earlier can be extended to adopt and conform to TextRepresentable:
extension Dice: TextRepresentable {
func asText() -> String {
return "A \(sides)-sided dice"
}
}
This extension adopts the new protocol in exactly the same way as if Dice had provided it
in its original implementation. The protocol name is provided after the type name,
separated by a colon, and an implementation of all requirements of the protocol is
provided within the extension’s curly braces.
Any Dice instance can now be treated as TextRepresentable:
let d12 = Dice(sides: 12, generator: LinearCongruentialGenerator())
println(d12.asText())
// prints "A 12-sided dice"
Similarly, the SnakesAndLadders game class can be extended to adopt and conform to the
TextRepresentable protocol:
extension SnakesAndLadders: TextRepresentable {
func asText() -> String {
return "A game of Snakes and Ladders with \(finalSquare) squares"
}
}
println(game.asText())
// prints "A game of Snakes and Ladders with 25 squares"
Declaring Protocol Adoption with an Extension
If a type already conforms to all of the requirements of a protocol, but has not yet stated
that it adopts that protocol, you can make it adopt the protocol with an empty extension:
struct Hamster {
var name: String
func asText() -> String {
return "A hamster named \(name)"
}
}
extension Hamster: TextRepresentable {}
Instances of Hamster can now be used wherever TextRepresentable is the required type:
let simonTheHamster = Hamster(name: "Simon")
let somethingTextRepresentable: TextRepresentable = simonTheHamster
println(somethingTextRepresentable.asText())
// prints "A hamster named Simon"
N O T E
Types do not automatically adopt a protocol just by satisfying its requirements. They must always explicitly
declare their adoption of the protocol.
Collections of Protocol Types
A protocol can be used as the type to be stored in a collection such as an array or a
dictionary, as mentioned in Protocols as Types. This example creates an array of
TextRepresentable things:
let things: TextRepresentable[] = [game, d12, simonTheHamster]
It is now possible to iterate over the items in the array, and print each item’s textual
representation:
for thing in things {
println(thing.asText())
}
// A game of Snakes and Ladders with 25 squares
// A 12-sided dice
// A hamster named Simon
Note that the thing constant is of type TextRepresentable. It is not of type Dice, or DiceGame, or
Hamster, even if the actual instance behind the scenes is of one of those types.
Nonetheless, because it is of type TextRepresentable, and anything that is TextRepresentable is
known to have an asText method, it is safe to call thing.asText each time through the loop.
Protocol Inheritance
A protocol can inherit one or more other protocols and can add further requirements on
top of the requirements it inherits. The syntax for protocol inheritance is similar to the
syntax for class inheritance, but with the option to list multiple inherited protocols,
separated by commas:
protocol InheritingProtocol: SomeProtocol, AnotherProtocol {
// protocol definition goes here
}
Here’s an example of a protocol that inherits the TextRepresentable protocol from above:
protocol PrettyTextRepresentable: TextRepresentable {
func asPrettyText() -> String
}
This example defines a new protocol, PrettyTextRepresentable, which inherits from
TextRepresentable. Anything that adopts PrettyTextRepresentable must satisfy all of the
requirements enforced by TextRepresentable, plus the additional requirements enforced by
PrettyTextRepresentable. In this example, PrettyTextRepresentable adds a single requirement to
provide an instance method called asPrettyText that returns a String.
The SnakesAndLadders class can be extended to adopt and conform to PrettyTextRepresentable:
extension SnakesAndLadders: PrettyTextRepresentable {
func asPrettyText() -> String {
var output = asText() + ":¶
"
for index in 1...finalSquare {
switch board[index] {
case let ladder where ladder > 0:
output += "▲ "
case let snake where snake < 0:
output += "▼ "
default:
output += "○ "
}
}
return output
This extension states that it adopts the PrettyTextRepresentable protocol and provides an
implementation of the asPrettyText method for the SnakesAndLadders type. Anything that is
PrettyTextRepresentable must also be TextRepresentable, and so the asPrettyText implementation
starts by calling the asText method from the TextRepresentable protocol to begin an output
string. It appends a colon and a line break, and uses this as the start of its pretty text
representation. It then iterates through the array of board squares, and appends an emoji
representation for each square:
The method implementation can now be used to print a pretty text description of any
SnakesAndLadders instance:
println(game.asPrettyText())
// A game of Snakes and Ladders with 25 squares:
// ○ ○ ▲ ○ ○ ▲ ○ ○ ▲ ▲ ○ ○ ○ ▼ ○ ○ ○ ○ ▼ ○ ○ ▼ ○ ▼ ○
If the square’s value is greater than 0, it is the base of a ladder, and is
represented by ▲.
If the square’s value is less than 0, it is the head of a snake, and is represented by
▼.
Otherwise, the square’s value is 0, and it is a “free” square, represented by ○.
Protocol Composition
It can be useful to require a type to conform to multiple protocols at once. You can
combine multiple protocols into a single requirement with a protocol composition.
Protocol compositions have the form protocol. You can list as many
protocols within the pair of angle brackets (<>) as you need, separated by commas.
Here’s an example that combines two protocols called Named and Aged into a single
protocol composition requirement on a function parameter:
protocol Named {
var name: String { get }
}
protocol Aged {
var age: Int { get }
}
struct Person: Named, Aged {
var name: String
var age: Int
wishHappyBirthday(celebrator: protocol) {
println("Happy birthday \(celebrator.name) - you're \(celebrator.age)!")
birthdayPerson = Person(name: "Malcolm", age: 21)
wishHappyBirthday(birthdayPerson)
prints "Happy birthday Malcolm - you're 21!"
This example defines a protocol called Named, with a single requirement for a gettable String
property called name. It also defines a protocol called Aged, with a single requirement for a
gettable Int property called age. Both of these protocols are adopted by a structure called
Person.
The example also defines a function called wishHappyBirthday, which takes a single parameter
called celebrator. The type of this parameter is protocol, which means “any type
that conforms to both the Named and Aged protocols.” It doesn’t matter what specific type is
passed to the function, as long as it conforms to both of the required protocols.
The example then creates a new Person instance called birthdayPerson and passes this new
instance to the wishHappyBirthday function. Because Person conforms to both protocols, this is a
valid call, and the wishHappyBirthday function is able to print its birthday greeting.
N O T E
Protocol compositions do not define a new, permanent protocol type. Rather, they define a temporary local
protocol that has the combined requirements of all protocols in the composition.
Checking for Protocol Conformance
You can use the is and as operators described in Type Casting to check for protocol
conformance, and to cast to a specific protocol. Checking for and casting to a protocol
follows exactly the same syntax as checking for and casting to a type:
This example defines a protocol called HasArea, with a single property requirement of a
gettable Double property called area:
@objc protocol HasArea {
var area: Double { get }
}
N O T E
You can check for protocol conformance only if your protocol is marked with the @objc attribute, as seen for
the HasArea protocol above. This attribute indicates that the protocol should be exposed to Objective-C code
and is described in Using Swift with Cocoa and Objective-C. Even if you are not interoperating with Objective-C,
you need to mark your protocols with the @objc attribute if you want to be able to check for protocol
conformance.
Note also that @objc protocols can be adopted only by classes, and not by structures or enumerations. If you
mark your protocol as @objc in order to check for conformance, you will be able to apply that protocol only to
class types.
The is operator returns true if an instance conforms to a protocol and returns false if
it does not.
The as? version of the downcast operator returns an optional value of the
protocol’s type, and this value is nil if the instance does not conform to that
protocol.
The as version of the downcast operator forces the downcast to the protocol type
and triggers a runtime error if the downcast does not succeed.
Here are two classes, Circle and Country, both of which conform to the HasArea protocol:
class Circle: HasArea {
let pi = 3.1415927
var radius: Double
var area: Double { return pi * radius * radius }
init(radius: Double) { self.radius = radius }
}
class Country: HasArea {
var area: Double
init(area: Double) { self.area = area }
The Circle class implements the area property requirement as a computed property, based
on a stored radius property. The Country class implements the area requirement directly as a
stored property. Both classes correctly conform to the HasArea protocol.
Here’s a class called Animal, which does not conform to the HasArea protocol:
class Animal {
var legs: Int
init(legs: Int) { self.legs = legs }
}
The Circle, Country and Animal classes do not have a shared base class. Nonetheless, they are
all classes, and so instances of all three types can be used to initialize an array that
stores values of type AnyObject:
let objects: AnyObject[] = [
Circle(radius: 2.0),
Country(area: 243_610),
Animal(legs: 4)
]
The objects array is initialized with an array literal containing a Circle instance with a radius
of 2 units; a Country instance initialized with the surface area of the United Kingdom in
square kilometers; and an Animal instance with four legs.
The objects array can now be iterated, and each object in the array can be checked to see
if it conforms to the HasArea protocol:
for object in objects {
if let objectWithArea = object as? HasArea {
println("Area is \(objectWithArea.area)")
} else {
println("Something that doesn't have an area")
}
}
// Area is 12.5663708
// Area is 243610.0
Something that doesn't have an area
Whenever an object in the array conforms to the HasArea protocol, the optional value
returned by the as? operator is unwrapped with optional binding into a constant called
objectWithArea. The objectWithArea constant is known to be of type HasArea, and so its area
property can be accessed and printed in a type-safe way.
Note that the underlying objects are not changed by the casting process. They continue
to be a Circle, a Country and an Animal. However, at the point that they are stored in the
objectWithArea constant, they are only known to be of type HasArea, and so only their area
property can be accessed.
Optional Protocol Requirements
You can define optional requirements for protocols, These requirements do not have to
be implemented by types that conform to the protocol. Optional requirements are
prefixed by the @optional keyword as part of the protocol’s definition.
An optional protocol requirement can be called with optional chaining, to account for the
possibility that the requirement was not implemented by a type that conforms to the
protocol. For information on optional chaining, see Optional Chaining.
You check for an implementation of an optional requirement by writing a question mark
after the name of the requirement when it is called, such as someOptionalMethod?(someArgument).
Optional property requirements, and optional method requirements that return a value,
will always return an optional value of the appropriate type when they are accessed or
called, to reflect the fact that the optional requirement may not have been implemented.
N O T E
Optional protocol requirements can only be specified if your protocol is marked with the @objc attribute. Even if
you are not interoperating with Objective-C, you need to mark your protocols with the @objc attribute if you
want to specify optional requirements.
Note also that @objc protocols can be adopted only by classes, and not by structures or enumerations. If you
mark your protocol as @objc in order to specify optional requirements, you will only be able to apply that
protocol to class types.
The following example defines an integer-counting class called Counter, which uses an
external data source to provide its increment amount. This data source is defined by the
CounterDataSource protocol, which has two optional requirements:
@objc protocol CounterDataSource {
@optional func incrementForCount(count: Int) -> Int
@optional var fixedIncrement: Int { get }
}
The CounterDataSource protocol defines an optional method requirement called incrementForCount
and an optional property requirement called fixedIncrement. These requirements define two
different ways for data sources to provide an appropriate increment amount for a Counter
instance.
N O T E
Strictly speaking, you can write a custom class that conforms to CounterDataSource without implementing
either protocol requirement. They are both optional, after all. Although technically allowed, this wouldn’t make
for a very good data source.
The Counter class, defined below, has an optional dataSource property of type CounterDataSource?:
@objc class Counter {
var count = 0
var dataSource: CounterDataSource?
func increment() {
if let amount = dataSource?.incrementForCount?(count) {
count += amount
} else if let amount = dataSource?.fixedIncrement? {
count += amount
}
The Counter class stores its current value in a variable property called count. The Counter class
also defines a method called increment, which increments the count property every time the
method is called.
The increment method first tries to retrieve an increment amount by looking for an
implementation of the incrementForCount method on its data source. The increment method uses
optional chaining to try to call incrementForCount, and passes the current count value as the
method’s single argument.
Note two levels of optional chaining at play here. Firstly, it is possible that dataSource may
be nil, and so dataSource has a question mark after its name to indicate that incrementForCount
should only be called if dataSource is non-nil. Secondly, even if dataSource does exist, there is
no guarantee that it implements incrementForCount, because it is an optional requirement.
This is why incrementForCount is also written with a question mark after its name.
Because the call to incrementForCount can fail for either of these two reasons, the call returns
an optional Int value. This is true even though incrementForCount is defined as returning a nonoptional
Int value in the definition of CounterDataSource.
After calling incrementForCount, the optional Int that it returns is unwrapped into a constant
called amount, using optional binding. If the optional Int does contain a value—that is, if the
delegate and method both exist, and the method returned a value—the unwrapped amount
is added onto the stored count property, and incrementation is complete.
If it is not possible to retrieve a value from the incrementForCount method—either because
dataSource is nil, or because the data source does not implement incrementForCount—then the
increment method tries to retrieve a value from the data source’s fixedIncrement property
instead. The fixedIncrement property is also an optional requirement, and so its name is also
written using optional chaining with a question mark on the end, to indicate that the
attempt to access the property’s value can fail. As before, the returned value is an
optional Int value, even though fixedIncrement is defined as a non-optional Int property as
part of the CounterDataSource protocol definition.
Here’s a simple CounterDataSource implementation where the data source returns a constant
value of 3 every time it is queried. It does this by implementing the optional fixedIncrement
property requirement:
class ThreeSource: CounterDataSource {
let fixedIncrement = 3
}
You can use an instance of ThreeSource as the data source for a new Counter instance:
var counter = Counter()
counter.dataSource = ThreeSource()
for _ in 1...4 {
counter.increment()
println(counter.count)
}
// 3
// 6
// 9
The code above creates a new Counter instance; sets its data source to be a new ThreeSource
instance; and calls the counter’s increment method four times. As expected, the counter’s
count property increases by three each time increment is called.
Here’s a more complex data source called TowardsZeroSource, which makes a Counter instance
count up or down towards zero from its current count value:
class TowardsZeroSource: CounterDataSource {
func incrementForCount(count: Int) -> Int {
if count == 0 {
return 0
} else if count < 0 {
return 1
} else {
return -1
}
The TowardsZeroSource class implements the optional incrementForCount method from the
CounterDataSource protocol and uses the count argument value to work out which direction to
count in. If count is already zero, the method returns 0 to indicate that no further counting
should take place.
You can use an instance of TowardsZeroSource with the existing Counter instance to count from -
4 to zero. Once the counter reaches zero, no more counting takes place:
counter.count = -4
counter.dataSource = TowardsZeroSource()
for _ in 1...5 {
counter.increment()
println(counter.count)
}
// -3
// -2
// -1

chapter24
# 24 프로토콜제네릭

Write here...
chapter25
# 25 제네릭

Write here..
고급 연산자

기본 연산자 항목에서 설명했던 연산자들에 더하여, Swift는 훨씬 다양한 방법으로 값을 다루는 몇개의 고급 연산자들을 제공합니다. 이들은 당신이 C와 Objective-C에서 부터 친근하게 여겼던 비트를 다루는 연산자들 모두를 포함합니다.

C에서의 산술 연산자들과는 다르게, Swift에서의 산술 연산자들은 기본적으로 넘침(Overflow)이 일어나지 않습니다. 넘치는 동작(Overflow behavior)은 오류로써 잡히고 보고됩니다. 넘치는 동작을 허용하기 위해서, 넘침을 기본으로 하는 산술 연산들 중에 Swift의 두번째 집합을 사용해야 합니다. 예를 들어, 넘침 덧셈(overflow addition, &+)이 그러한 집합에 속합니다. 모든 넘침 연산자들은 엠퍼샌드(ampersand, &)를 가지고 시작합니다.

당신이 당신 소유의 구조체들과 클래스, 그리고 열거자들을 선언할때, 이들 커스텀 타입들에 대해서 표준 Swift 연산자들의 독자적인 구현들(own implementations)을 제공하는데 유용할 수 있습니다. Swift는 이들 연산자들의 맞춤형(tailored) 구현들을 제공하고 그들의 행동이 당신이 만든 각각의 타입에 대해서 무엇을 해야할지를 정확하게 결정하기 쉽게 만듭니다. (역자 주, operator overload)

당신은 연산자들을 재정의하는데 아무런 제한이 없습니다. Swift는 당신에게 당신 자신의 맞춤형 중간(infix), 전위(prefix), 후위(postfix) 그리고 할당 연산자들을 정의하는데 자유를 줍니다. 그리고 그것들의 우선순위와 결합순위 역시 자유롭게 정의가 가능합니다. 이들 연산자들은 마치 이미 선언된 연산자들 처럼 당신의 코드 안에 사용되고 적용될 수 있고, 당신은 당신이 정의한 맞춤형 연산자들을 지원하도록 이미 존재하는 타입들조차 확장할 수 있습니다.

**비트 연산자들**

비트 연산자들은 당신에게 하나의 데이터 구조체 안에 있는 개개의 가공되지 않은 데이터 비트들(raw data bits)을 다루는 것을 허용합니다. 그들은 종종 그래픽 프로그래밍과 디바이스 드라이버 프로그래밍(device driver creation)과 같은 저수준 프로그래밍에 사용됩니다. 또한 비트 연산자들은 당신이 외부의 입력들(external source)로부터 오는 가공되지 않은 데이터(raw data)를 가지고 작업할때 유용합니다. 예를 들어, 커스텀 프로토콜을 이용한 통신에서 데이터의 부호화(encoding)와 복호화(decoding)과 같은 것들이 그것입니다.

Swift는 C에서 발견되는 모든 비트 연산자들을 지원합니다. 이는 아래에서 좀더 자세히 설명드리겠습니다.

**비트 NOT 연산자**

비트 NOT 연산자(~)는 다음과 같이 숫자의 모든 비트들을 뒤집습니다.(invert)



비트 NOT 연산자는 전위연산자입니다. 그리고 공백없이, 연산하는 값 바로 앞에 나타납니다.

1: let initialBits: UInt8 = 0b00001111
2: let invertedBits = ~initialBits // equals 11110000

UInt8 정수들은 8개의 비트를 가지며, 0에서부터 255까지의 임의의 값을 저장할 수 있습니다. 이 예는 UInt8 정수 변수를, 최초의 4개 비트는 0으로, 나머지 4개비트는 1로 설정한, 이진 값 00001111을 가지도록 초기화합니다. 이것은 십진수 15와 동일한 것입니다.

다음 줄에서, 비트 NOT 연산자는 invertedBits라 불리우는 새로운 상수를 생성하는데 사용합니다. 이것은 initialBits와 동일하지만 모든 비트들이 뒤집어져 있습니다. 다시말해, 이때 initialBit의 비트들중에 0은 1이되고, 1은 0이 됩니다. "그러므로" invertedBits의 값은 11110000이 됩니다. 이것은 부호없는 십진수 240과 동일합니다.

**비트 AND 연산자**

비트 AND 연산자(&)는 두 숫자의 비트들을 결합합니다. 비트들이 다음과 같이 양쪽 입력 숫자들에서 1과 같아야만 비트들이 1로 설정되는 새로운 숫자을 돌려받습니다.(""""좀더 명확하게 이해되도록 수정해야할 필요가 있음"""")



아래의 예에서, firstSixBits변수와 lastSixBits양쪽의 값들은 4개의 중간 비트가 1로 되어있습니다. 비트 AND 연산자는 그들을 부호없는 십진수 60과 동일한 숫자인 00111100로 만들도록 조합합니다.

1: let firstSixBits: UInt8 = 0b11111100
2: let lastSixBits: UInt8 = 0b00111111
3: let middleFourBits = firstSixBits & lastSixBits // equals 00111100

**비트 OR 연산자**

비트 OR 연산자(|)는 두 수의 비트들을 비교합니다. 연산자는 만일 다음처럼 입력 수들 중에 어떤 하나가 비트 1이면, 비트가 1로 설정된 새로운 수를 돌려줍니다.



아래의 예제에서, someBits와 moreBits의 값은 1로 설정된 다른 비트들을 가집니다. 비트 OR 연산자는 그들을 부호없는 십진수 256와 동일한 숫자인 11111110으로 만들어지도록 조합합니다.

1:let someBits: UInt8 = 0b10110010
2:let moreBits: UInt8 = 0b01011110
3:let combinedbits = someBits | moreBits // equals 11111110”

**비트 XOR 연산자**

비트 XOR 연산자 또는 배타적(exclusive) OR 연산자 (^)는 두 수의 비트들을 비교합니다. 연산자는 다음과 같이 입력 비트들이 다르면 1로 같으면 0으로 설정되어진 새로운 수를 돌려받습니다.



아래 예에서, firstBits와 otherBits 각각의 값들은 하나의 위치에서 1로 설정된 하지만 다른 변수에서는 그렇지 않은 비트를 가집니다. 비트 XOR 연산자는 그것들의 출력 값에서 이들 비트들의 양쪽을 1로 설정합니다. firstBits와 otherBits에서 모든 다른 비트들은 같으며, 이것은 다음과 같이 출력 값에서 0으로 나타납니다.

1:let firstBits: UInt8 = 0b00010100
2:let otherBits: UInt8 = 0b00000101
3:let outputBits = firstBits ^ otherBits // equals 00010001

**비트 왼쪽 및 오른쪽 이동(shift) 연산자들**

비트 왼쪽 이동 연산자(<<)와 비트 오른쪽 이동 연산자(>>)는 수에서 아래 정의된 규칙에 따라서, 특정 수의 위치(a certain number of places)로 모든 비트들을 왼쪽 또는 오른쪽으로 이동시킵니다.

비트 왼쪽 그리고 오른쪽 이동은 2의 인수로 정수에 곱한 것과 나눈 것의 효과를 가집니다. 왼쪽으로 한 자리만큼 정수의 비트들을 이동하는 것은 값을 두배로 하는 것과 같은 효과를 나타냅니다. 마찬가지로 오른쪽으로 이동하는 것은 2로 나누는 것과 동일한 효과를 가집니다.

**부호없는 정수들에 대한 이동 방법**

부호없는 정수의 비트 이동은 다음처럼 합니다.

1. 존재하는 비트들은 요청된 수의 위치로(the requested number of places) 왼쪽 또는 오른쪽으로 이동되어 집니다.
2. 정수 공간의 크기를 넘어 이동된 비트들은 버려집니다.
3. 원래의 비트들이 이동되고 남은 자리에 0이 삽입됩니다.

이 접근은 논리적 이동(또는 옮김)으로써 알려져 있습니다.

아래의 그림은 11111111<<1의 결과를 보여줍니다.(여기서는 왼쪽으로 1만큼 이동하는 것을 말합니다.) 그리고 11111111>>1(이것은 오른쪽으로 1만큼 이동하는 것을 말합니다.) 여기서 파란색 비트들은 이동된 비트들을 말하며, 회색 비트들은 버려진 것을 말합니다. 그리고 오랜지색의 0은 삽입된 것을 말합니다.

<>

여기서는 Swift 코드 안에서 어떻게 비트 이동을 하는지를 다음의 실제 코드로 보여줍니다.

1:let shiftBits: UInt8 = 4 // 00000100 in binary
2:shiftBits << 1 // 00001000
3:shiftBits << 2 // 00010000
4:shiftBits << 5 // 10000000
5:shiftBits << 6 // 00000000
6:shiftBits >> 2 // 00000001

당신은 다음과 같이 다른 데이터 타입들안에 있는 값들을 부호화하기 위해서 그리고 복호화하기 위해서 비트 이동을 사용할 수 있습니다.

1:let pink: UInt32 = 0xCC6699
2:let redComponent = (pink & 0xFF0000) >> 16 // redComponent is 0xCC, or 204
3:let greenComponent = (pink & 0x00FF00) >> 8 // greenComponent is 0x66, or 102
4:let blueComponent = pink & 0x0000FF // blueComponent is 0x99, or 153

이 예제는 핑크색에 대한 Cascading Style Sheets 색 값을 저장하기 위해 pink로 불리우는 UInt32 타입의 상수를 사용합니다. CSS 컬러 값 #CC6699는 Swift의 16진수 표현으로 0xCC6699가 됩니다. 이 색깔은 비트 AND 연산자(&)와 비트 오른쪽 이동 연산자(>>)를 사용하여 빨간색 (CC), 녹색(66), 파란색 (99) 요소들로 나누어서 나타낼 수 있습니다.

chapter26
Deleted file
chapter27
Deleted file
chapter7
# 07 통제 흐름

Write here...
제어문 (Control Flow)

조건문(conditionals)을 만들 때에는 `if`와 `switch`를 사용하세요. 그리고 순환문(루프문, loops)을 만들 때에는 `for-in`나 `for`, `while`, `do-while`을 사용하세요. 조건이나 순환문 변수(loop variable)를 감싸주는 괄호 ( )는 옵션입니다. 본문을 감싸는 { }는 필수입니다.

```
let individual Scores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
if score > 50 {
teamScore += 3
} else {
teamScore += 1
}
}
Score
```

'if'문 안에서, 조건을 나타내는 부분은 부울 식(참 거짓, Boolean expression)이어야 합니다. 즉, 다음과 같이 쓰면 에러가 납니다.

```
if score {...}
```

조건부를 이렇게 score라고만 써주면, 에러가 나지, 프로그램이 알아서 score를 0과 비교해주지 않습니다.

조건부에서 쓴 변수가 값을 가지지 않을 수도 있는 경우에는 `if`하고 `let`을 같이 쓸 수 있습니다.

이러한 값들은 **선택적(optional)**이라고 합니다. 선택적인 값은, 값을 가질 수도 있고, 값을 안 가질 수도 있습니다. 값을 안 가지는 경우에는 `nil`값을 가집니다.

어떤 값이 선택적이라고 표시하려면 값의 형(type) 뒤에다가 물음표 `?`를 붙여 줍니다.

```
var optionalString: String? = "Hello"
optionalString == nil
var optionalName: String? = "John Appleseed"
var greeting = "Hello! "

if let name = optionalName {
greeting = "Hello, \(name)"
}
```

> 실험해 보세요 - optionalName을 nil로 바꿔보세요. 어떤 인사말이 나오나요? optionalName의 값이 nil인 경우에 다른 인사말을 보여주는 else절을 추가해 보세요.

옵션 값이 nil인 경우에, 조건부는 거짓(false)이 되고, {} 안에 있는 코드는 실행되지 않습니다. 옵션 값이 nil이 아닌 경우에는, 선택값이 unwrapped되고 let 뒷 부분에서 상수에 할당됩니다. 이렇게 되면 코드 블럭 내에서 unwrapped value가 available한 상태가 됩니다.

`switch` 명령어는 모든 종류의 데이터를 지원하며 아주 다양한 종류의 비교 연산을 지원합니다 - 정수형 데이터에 국한되지 않으며, 등가인지 확인하는 연산에 국한되지 않습니다.

```
let vegetable = "red pepper"

switch vegetable {
case "celery":
let vegetableComment = "Add some raisins and make ants on a log. "
case "cucumber", "watercress":
let vegetableComment = "That would make a good tea sandwich. "
case let x where x. hasSuffi x("pepper"):
let vegetableComment = "Is it a spicy \(x)?"
default:
vegetableComment = "Everything tastes good in soup. "
```

> 실험해 보세요 - 디폴트 경우(default case)를 제거해 보세요. 어떤 에러가 나오나요?

프로그램은 `switch`안에 있는 경우 중, 조건에 해당하는 case안에 있는 코드를 실행한 후, `switch` 문에서 빠져나옵니다. 실행된 case 다음에 나오는 case 안에 있는 코드는 실행되지 않습니다. 따라서 각 case 안에 있는 코드의 마지막 부분에 break 문을 써줄 필요가 없습니다.

딕셔너리(dictionary) 안에 있는 각 항목(item)에 대해서 이터레이트(iterate)할 때는, `for-in`을 사용합니다. 이 때 각 키-값 쌍(key-value pair)에 대해서 이름 쌍을 사용합니다.

```
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci ": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]

var largest = 0
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
}
```

> 실험해 보세요 - 변수를 하나 더 추가해서, 가장 최근에 가장 큰 수는 무엇이었는지, 그 수는 어떤 종류였는지 추적하세요.

조건이 변하기 전까지는 코드 블럭(block of code)을 반복하고 싶다면 `while`을 사용하세요. 루프가 적어도 한 번은 반드시 실행되도록 하려면, 조건부를 끝부분에 쓰면 됩니다.

```
var n = 2
while n < 100 {
n = n * 2
}
n

var m = 2
do {
m = m * 2
} while m < 100
m
```

루프 안에서 인덱스(index)를 사용해도 됩니다. 사용하는 방법으로는 `..`(마침표 두 개)를 사용해서 인덱스의 범위를 설정하는 방법도 있고, 초기화/조건부/증가시키는 부분을 작성하는 방법도 있습니다. 두 종류 모두 하는 작업은 같습니다:

```
var firstForLoop = 0
for i in 0..3 {
firstForLoop += i
}
firstForLoop
```

```
var secondForLoop = 0
for var i = 0; i < 3; ++i {
secondForLoop += 1
}
SecondForLoop
```

최댓값을 안 쓰고 범위를 만들 때에는 `..`(마침표 두 개)를 사용하고, 최댓값과 최솟값을 모두 사용해서 범위를 만들 때에는 `...`(마침표 세 개)를 사용합니다.



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

## 함수 정의와 호출
함수를 정의할때 함수의 입력(파라메터)을 하나 이상의 이름이 있고 타입이 정해진 값으로 할 수 있습니다. 또한 값의 타입은 함수의 실행이 끝났을때 함수가 되돌려줄 수 있습니다 (반환 타입).
모든 함수는 함수명을 가지고 있으며, 함수명은 함수가 하는일을 설명해줍니다. 함수를 사용하기위해서 함수를 함수의 이름을 사용하여 "호출"하고 함수의 파라메터 타입들과 일치하는 입력 값들(아규먼트Arguments)을 넘겨줍니다. 함수의 입력값은 함수의 파라메터리스트와 언제나 일치해야합니다.
아래의 함수 예제 이름은 greetingForPerson입니다. 함수가 행하는 일이 바로 그것(사람에게 환영인사Greeting for person)이기 때문입니다. 입력으로 사람의 이름을 받아서 그 사람에 대한 환영 인사를 반환합니다. 이를 달성하기 위해 파라메터를 하나 정의하고 - personName이라는 String 값 - 반환 타입을 String으로 합니다. 그렇게 그 사람에 대한 인사를 포함하는 것입니다.
![images8-1jpg.txt](images8-1jpg.txt)
이 모든 정보들은 func 키워드 접두어를 쓰는 함수의 정의안에 포함이 되게도비니다. 함수의 반환 타입은 화살표(하이픈과 우측 꺽괄호) __'->'__를 사용하여 화살표 오른쪽에 표시합니다.
함수 정의는 함수가 무엇을 하는지, 무엇을 파라메터로 받는지 완료되었을때 무엇을 반환하는지 설명합니다. 함수 정의는 함수가 코드안에서 호출될때 명확하고 애매함이 없는 방법으로 사용될수 있게합니다:
![images8-2jpg.txt](images8-2jpg.txt)
sayHello 함수를 괄호안에 String 타입의 인수를 넣어서 호출합니다. 예를들면 sayHello("Anna") 처럼 말이죠. sayHello가 String타입을 반환하기에 sayHello함수는 println로 싸여서 호출될 수 있습니다. 이렇게 함으로서 println함수가 sayHello함수의 반환값을 위에 보이는 것처럼 출력할 수 있습니다.
sayHello함수의 몸체는 greeting이라는 새 String 상수를 선언하는 것으로 시작합니다. 그리고 greeting을 personName에 대한 단순한 환영인사로 설정합니다. 이 환영 인사는 return키워드를 통해 함수의 밖으로 되돌려지게 됩니다. return greeting이 실행 되면 함수의 실행은 끝나게되고, greeting의 현재 값을 돌려주게됩니다.
sayHello 함수를 다른 입력값으로 여러번 호출할 수 있습니다. 위의 예제는 입력값이 "Anna", "Brian" 일때를 각각 보여주고 있습니다. 함수는 사람(입력값)에 맞게끔 환영인사를 각각의 경우에 맞추어 돌려줍니다.
함수 몸체를 단순화하기 위해서는, 메시지의 생성과 반환을 한줄로 합치면 됩니다:
![images8-3jpg.txt](images8-3jpg.txt)

## Function Parameters and Return Values
Function parameters and return values are extremely flexible in Swi ft. You can define
anything from a simple uti l i ty function wi th a single unnamed parameter to a complex
function wi th expressive parameter names and di fferent parameter options.
##Multiple Input Parameters
Functions can have mul tiple input parameters, whi ch are wri tten wi thin the function’s
parentheses, separated by commas.
Thi s function takes a start and an end index for a hal f-open range, and works out how
many elements the range contains:
func hal fOpenRangeLength(start: Int, end: Int) -> Int {
return end - start
}
pri ntl n(hal fOpenRangeLength(1, 10))
// pri nts "9"
##Functions Without Parameters
Functions are not requi red to define input parameters. Here’s a function wi th no input
parameters, whi ch always returns the same Stri ng message whenever i t i s cal led:
func sayHel l oWorl d() -> Stri ng {
return "hel l o, w orl d"
}
pri ntl n(sayHel l oWorl d())
// pri nts "hel l o, w orl d"
The function defini tion sti l l needs parentheses after the function’s name, even though i t
does not take any parameters. The function name i s al so fol lowed by an empty pai r of
parentheses when the function i s cal led.
##Functions Without Return Values
Functions are not requi red to define a return type. Here’s a version of the sayHel l o function,
cal led w aveGoodbye, whi ch prints i ts own Stri ng value rather than returning i t:
func sayGoodbye(personName: Stri ng) {
pri ntl n("Goodbye, \(personName)! ")
}
sayGoodbye("Dave")
// pri nts "Goodbye, Dave! "
Because i t does not need to return a value, the function’s defini tion does not include the
return arrow (->) or a return type.
> N O T E
Stri ctl y speaki ng, the sayGoodbye functi on does sti l l return a val ue, even though no return val ue i s defi ned.
Functi ons w i thout a defi ned return type return a speci al val ue of type Voi d. T hi s i s si mpl y an empty tupl e, i n
effect a tupl e w i th zero el ements, w hi ch can be w ri tten as ().

The return value of a function can be ignored when i t i s cal led:
func pri ntAndCount(stri ngT oPri nt: Stri ng) -> Int {
pri ntl n(stri ngT oPri nt)
return countEl ements(stri ngT oPri nt)
}
func pri ntWi thoutCounti ng(stri ngT oPri nt: Stri ng) {
pri ntAndCount(stri ngT oPri nt)
}
pri ntAndCount("hel l o, w orl d")
// pri nts "hel l o, w orl d" and returns a val ue of 12
Wi thoutCounti ng("hel l o, w orl d")
i nts "hel l o, w orl d" but does not return a val ue
The fi rst function, pri ntAndCount, prints a string, and then returns i ts character count as an
Int. The second function, pri ntWi thoutCounti ng, cal l s the fi rst function, but ignores i ts return
value. When the second function i s cal led, the message i s sti l l printed by the fi rst
function, but the returned value i s not used.

> N O T E
Return val ues can be i gnored, but a functi on that says i t w i l l return a val ue must al w ays do so. A functi on w i th
a defi ned return type cannot al l ow control to fal l out of the bottom of the functi on w i thout returni ng a val ue,
and attempti ng to do so w i l l resul t i n a compi l e- ti me error.

## Functions with Multiple Return Values
You can use a tuple type as the return type for a function to return mul tiple values as
part of one compound return value.
The example below defines a function cal led count, whi ch counts the number of vowel s,
consonants, and other characters in a string, based on the standard set of vowel s and
consonants used in Ameri can Engl i sh:
func count(stri ng: Stri ng) -> (vow el s: Int, consonants: Int, others: Int) {
var vow el s = 0, consonants = 0, others = 0
for character i n stri ng {
sw i tch Stri ng(character). l ow ercaseStri ng {
case "a", "e", "i ", "o", "u":
++vow el s
case "b", "c", "d", "f", "g", "h", "j", "k", "l ", "m",
"n", "p", "q", "r", "s", "t", "v", "w ", "x", "y", "z":
++consonants
defaul t:
++others
}
eturn (vow el s, consonants, others)
You can use thi s count function to count the characters in an arbi trary string, and to
retrieve the counted total s as a tuple of three named Int values:
l et total = count("some arbi trary stri ng! ")
pri ntl n("\(total . vow el s) vow el s and \(total . consonants) consonants")
// pri nts "6 vow el s and 13 consonants"
Note that the tuple’s members do not need to be named at the point that the tuple i s
returned from the function, because thei r names are al ready speci fied as part of the
function’s return type.
## Function Parameter Names
Al l of the above functions define parameter names for thei r parameters:
func someFuncti on(parameterName: Int) {
// functi on body goes here, and can use parameterName
// to refer to the argument val ue for that parameter
}
However, these parameter names are only used wi thin the body of the function i tsel f, and
cannot be used when cal l ing the function. These kinds of parameter names are known as
local parameter names, because they are only avai lable for use wi thin the function’s
body.
## External Parameter Names
Sometimes i t’s useful to name each parameter when you cal l a function, to indi cate the
purpose of each argument you pass to the function.
If you want users of your function to provide parameter names when they cal l your
function, define an external parameter name for each parameter, in addi tion to the local
parameter name. You wri te an external parameter name before the local parameter
name i t supports, separated by a space:
func someFuncti on(external ParameterName l ocal ParameterName: Int) {
// functi on body goes here, and can use l ocal ParameterName
// to refer to the argument val ue for that parameter
}
> N O T E
If you provi de an external parameter name for a parameter, that external name must al w ays be used w hen
cal l i ng the functi on.

As an example, consider the fol lowing function, whi ch joins two strings by inserting a
thi rd “joiner” string between them:
func joi n(s1: Stri ng, s2: Stri ng, joi ner: Stri ng) -> Stri ng {
return s1 + joi ner + s2
}
When you cal l thi s function, the purpose of the three strings that you pass to the function
i s unclear:
joi n("hel l o", "w orl d", ", ")
// returns "hel l o, w orl d"
To make the purpose of these Stri ng values clearer, define external parameter names for
each joi n function parameter:
func joi n(stri ng s1: Stri ng, toStri ng s2: Stri ng, w i thJoi ner joi ner: Stri ng)
-> Stri ng {
return s1 + joi ner + s2
}
In thi s version of the joi n function, the fi rst parameter has an external name of stri ng and a
local name of s1; the second parameter has an external name of toStri ng and a local name
of s2; and the thi rd parameter has an external name of w i thJoi ner and a local name of joi ner.
You can now use these external parameter names to cal l the function in a clear and
unambiguous way:
joi n(stri ng: "hel l o", toStri ng: "w orl d", w i thJoi ner: ", ")
// returns "hel l o, w orl d"
The use of external parameter names enables thi s second version of the joi n function to be
cal led in an expressive, sentence-l ike manner by users of the function, whi le sti l l
providing a function body that i s readable and clear in intent.

>N O T E
Consi der usi ng external parameter names w henever the purpose of a functi on’s arguments w oul d be uncl ear
to someone readi ng your code for the fi rst ti me. Y ou do not need to speci fy external parameter names i f the
purpose of each parameter i s cl ear and unambi guous w hen the functi on i s cal l ed.

## Shorthand External Parameter Names
If you want to provide an external parameter name for a function parameter, and the
local parameter name i s al ready an appropriate name to use, you do not need to wri te
the same name twi ce for that parameter. Instead, wri te the name once, and prefix the
name wi th a hash symbol (#). Thi s tel l s Swi ft to use that name as both the local
parameter name and the external parameter name.
Thi s example defines a function cal led contai nsCharacter, whi ch defines external parameter
names for both of i ts parameters by placing a hash symbol before thei r local parameter
names:
func contai nsCharacter(#stri ng: Stri ng, #characterT oFi nd: Character) -> Bool {
for character i n stri ng {
i f character == characterT oFi nd {
return true
}
}
return fal se
}
Thi s function’s choi ce of parameter names makes for a clear, readable function body,
whi le al so enabl ing the function to be cal led wi thout ambigui ty:
l et contai nsAVee = contai nsCharacter(stri ng: "aardvark", characterT oFi nd: "v")
// contai nsAVee equal s true, because "aardvark" contai ns a "v"
## Default Parameter Values
You can define a defaul t value for any parameter as part of a function’s defini tion. If a
defaul t value i s defined, you can omi t that parameter when cal l ing the function.

>N O T E
Pl ace parameters w i th defaul t val ues at the end of a functi on’s parameter l i st. T hi s ensures that al l cal l s to the
functi on use the same order for thei r non-defaul t arguments, and makes i t cl ear that the same functi on i s
bei ng cal l ed i n each case.

Here’s a version of the joi n function from earl ier, whi ch provides a defaul t value for i ts joi ner
parameter:
func joi n(stri ng s1: Stri ng, toStri ng s2: Stri ng,
w i thJoi ner joi ner: Stri ng = " ") -> Stri ng {
return s1 + joi ner + s2
}
If a string value for joi ner i s provided when the joi n function i s cal led, that string value i s
used to join the two strings together, as before:
joi n(stri ng: "hel l o", toStri ng: "w orl d", w i thJoi ner: "-")
// returns "hel l o-w orl d"
However, i f no value of joi ner i s provided when the function i s cal led, the defaul t value of a
single space (" ") i s used instead:
joi n(stri ng: "hel l o", toStri ng: "w orl d")
// returns "hel l o w orl d"
## External Names for Parameters with Default Values
In most cases, i t i s useful to provide (and therefore requi re) an external name for any
parameter wi th a defaul t value. Thi s ensures that the argument for that parameter i s
clear in purpose i f a value i s provided when the function i s cal led.
To make thi s process easier, Swi ft provides an automati c external name for any defaul ted
parameter you define, i f you do not provide an external name yoursel f. The automati c
external name i s the same as the local name, as i f you had wri tten a hash symbol before
the local name in your code.
Here’s a version of the joi n function from earl ier, whi ch does not provide external names
for any of i ts parameters, but sti l l provides a defaul t value for i ts joi ner parameter:
func joi n(s1: Stri ng, s2: Stri ng, joi ner: Stri ng = " ") -> Stri ng {
return s1 + joi ner + s2
}
In thi s case, Swi ft automati cal ly provides an external parameter name of joi ner for the
defaul ted parameter. The external name must therefore be provided when cal l ing the
function, making the parameter’s purpose clear and unambiguous:
joi n("hel l o", "w orl d", joi ner: "-")
// returns "hel l o-w orl d"
>N O T E
Y ou can opt out of thi s behavi or by w ri ti ng an underscore (_) i nstead of an expl i ci t external name w hen you
defi ne the parameter. How ever, external names for defaul ted parameters are al w ays preferred w here
appropri ate
Function
함수는 특정 일을 수행하는 자기 완결성(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)나 반환 타입을 포함하지 않습니다.

> N O T E
엄밀히 말하자면, `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`은 첫번째 함수를 호출합니다. 하지만 반환값은 무시합니다. 두번째 함수가 호출되면 메시지는 첫번째 함수에 의해 여전히 출력되지만, 첫번째 함수의 반환값은 사용되지 않습니다.

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

## 여러개의 반환값을 가지는 함수
튜플 타입은 하나의 합성된 반환값으로서 함수의 반환에 사용될 수 있습니다.
아래의 예제는 `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
}
```
> N O T E
만약 외부 파라메터 이름이 파라메터에 대해 제공된다면, 외부 파라메터 이름은 언제나 함수 호출시에 사용되어야 합니다.

예를 들어 다음과 같은 함수가 있다고 합시다. 이 함수는 두 문자열 사이에 `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 l providing a function body that is readable and clear in intent.)

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

## 단축 외부 파라메터 이름
만약 함수의 외부 파라메터 이름을 제공하려 할때 이미 해당 파라메터의 내부 이름(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) 파라메터 값
함수 정의의 일부로서 파라메터의 기본 값을 지정해줄 수 있다. 기본값이 지정되어 있으면 함수를 호출할때 해당 파라메터를 생략할 수 있다.

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

앞서 보인 `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"
```
>N O T E
함수를 정의할때 명시적인 외부 이름을 쓰는 것 대신에 밑줄(`_`)을 씀으로써 이 동작을 수행하지 않게 할 수 있다. 하지만 기본값을 가진 파라메터에 적절한 외부 이름을 제공하는것은 언제나 바람직하다
.

## Variadic Parameters
A variadi c parameter accepts zero or more values of a speci fied type. You use a variadi c
parameter to speci fy that the parameter can be passed a varying number of input values
when the function i s cal led. Wri te variadi c parameters by inserting three period
characters (. . .) after the parameter’s type name.
The values passed to a variadi c parameter are made avai lable wi thin the function’s body
as an array of the appropriate type. For example, a variadi c parameter wi th a name of
numbers and a type of Doubl e. . . i s made avai lable wi thin the function’s body as a constant
array cal led numbers of type Doubl e[].
The example below cal culates the ari thmeti c mean (al so known as the average) for a l i st
of numbers of any length:
func ari thmeti cMean(numbers: Doubl e. . . ) -> Doubl e {
var total : Doubl e = 0
for number i n numbers {
total += number
}
return total / Doubl e(numbers. count)
}
ari thmeti cMean(1, 2, 3, 4, 5)
// returns 3. 0, w hi ch i s the ari thmeti c mean of these fi ve numbers
meti cMean(3, 8, 19)
turns 10. 0, w hi ch i s the ari thmeti c mean of these three numbers
> N O T E
A functi on may have at most one vari adi c parameter, and i t must al w ays appear l ast i n the parameter l i st, to
avoi d ambi gui ty w hen cal l i ng the functi on w i th mul ti pl e parameters.
If your functi on has one or more parameters w i th a defaul t val ue, and al so has a vari adi c parameter, pl ace
the vari adi c parameter after al l the defaul ted parameters at the very end of the l i st.

## Constant and Variable Parameters
Function parameters are constants by defaul t. Trying to change the value of a function
parameter from wi thin the body of that function resul ts in a compi le-time error. Thi s
means that you can’t change the value of a parameter by mi stake.
However, sometimes i t i s useful for a function to have a variable copy of a parameter’s
value to work wi th. You can avoid defining a new variable yoursel f wi thin the function by
speci fying one or more parameters as variable parameters instead. Variable parameters
are avai lable as variables rather than as constants, and give a new modi fiable copy of the
parameter’s value for your function to work wi th.
Define variable parameters by prefixing the parameter name wi th the keyword var:
func al i gnRi ght(var stri ng: Stri ng, count: Int, pad: Character) -> Stri ng {
l et amountT oPad = count - countEl ements(stri ng)
for _ i n 1. . . amountT oPad {
stri ng = pad + stri ng
}
return stri ng
}
l et ori gi nal Stri ng = "hel l o"
l et paddedStri ng = al i gnRi ght(ori gi nal Stri ng, 10, "-")
addedStri ng i s equal to "- - - - -hel l o"
i gi nal Stri ng i s sti l l equal to "hel l o"
Thi s example defines a new function cal led al i gnRi ght, whi ch al igns an input string to the
right edge of a longer output string. Any space on the left i s fi l led wi th a speci fied
padding character. In thi s example, the string "hel l o" i s converted to the string "- - - - -hel l o".
The al i gnRi ght function defines the input parameter stri ng to be a variable parameter. Thi s
means that stri ng i s now avai lable as a local variable, ini tial i zed wi th the passed-in string
value, and can be manipulated wi thin the body of the function.
The function starts by working out how many characters need to be added to the left of
stri ng in order to right-al ign i t wi thin the overal l string. Thi s value i s stored in a local
constant cal led amountT oPad. The function then adds amountT oPad copies of the pad character
to the left of the exi sting string and returns the resul t. It uses the stri ng variable parameter
for al l i ts string manipulation.

>N O T E
T he changes you make to a vari abl e parameter do not persi st beyond the end of each cal l to the functi on,
and are not vi si bl e outsi de the functi on’s body. T he vari abl e parameter onl y exi sts for the l i feti me of that
functi on cal l .

## In-Out Parameters
Variable parameters, as described above, can only be changed wi thin the function i tsel f.
If you want a function to modi fy a parameter’s value, and you want those changes to
persi st after the function cal l has ended, define that parameter as an in-out parameter
instead.
You wri te an in-out parameter by placing the i nout keyword at the start of i ts parameter
defini tion. An in-out parameter has a value that i s passed in to the function, i s modi fied
by the function, and i s passed back out of the function to replace the original value.
You can only pass a variable as the argument for an in-out parameter. You cannot pass a
constant or a l i teral value as the argument, because constants and l i teral s cannot be
modi fied. You place an ampersand (&) di rectly before a variable’s name when you pass i t
as an argument to an inout parameter, to indi cate that i t can be modi fied by the function.
>N O T E
In-out parameters cannot have defaul t val ues, and vari adi c parameters cannot be marked as i nout. If you
mark a parameter as i nout, i t cannot al so be marked as var or l et.

Here’s an example of a function cal led sw apT w oInts, whi ch has two in-out integer
parameters cal led a and b:
func sw apT w oInts(i nout a: Int, i nout b: Int) {
l et temporaryA = a
a = b
b = temporaryA
}
The sw apT w oInts function simply swaps the value of b into a, and the value of a into b. The
function performs thi s swap by storing the value of a in a temporary constant cal led
temporaryA, assigning the value of b to a, and then assigning temporaryA to b.
You can cal l the sw apT w oInts function wi th two variables of type Int to swap thei r values.
Note that the names of someInt and anotherInt are prefixed wi th an ampersand when they
are passed to the sw apT w oInts function:
var someInt = 3
var anotherInt = 107
sw apT w oInts(&someInt, &anotherInt)
pri ntl n("someInt i s now \(someInt), and anotherInt i s now \(anotherInt)")
// pri nts "someInt i s now 107, and anotherInt i s now 3"
The example above shows that the original values of someInt and anotherInt are modi fied by
the sw apT w oInts function, even though they were original ly defined outside of the function.
>N O T E
In-out parameters are not the same as returni ng a val ue from a functi on. T he sw apT w oInts exampl e above
does not defi ne a return type or return a val ue, but i t sti l l modi fi es the val ues of someInt and anotherInt. Inout parameters are an al ternati ve w ay for a functi on to have an effect outsi de of the scope of i ts functi on
body.

## Function Types
Every function has a speci fi c function type, made up of the parameter types and the
return type of the function.
For example:
func addT w oInts(a: Int, b: Int) -> Int {
return a + b
}
func mul ti pl yT w oInts(a: Int, b: Int) -> Int {
return a * b
}
Thi s example defines two simple mathemati cal functions cal led addT w oInts and mul ti pl yT w oInts.
These functions each take two Int values, and return an Int value, whi ch i s the resul t of
performing an appropriate mathemati cal operation.
The type of both of these functions i s (Int, Int) -> Int. Thi s can be read as:
“A function type that has two parameters, both of type Int, and that returns a value of
type Int.”
Here’s another example, for a function wi th no parameters or return value:
func pri ntHel l oWorl d() {
pri ntl n("hel l o, w orl d")
}
The type of thi s function i s () -> (), or “a function that has no parameters, and returns Voi d.”
Functions that don’t speci fy a return value always return Voi d, whi ch i s equivalent to an
empty tuple in Swi ft, shown as ().
## Using Function Types
You use function types just l ike any other types in Swi ft. For example, you can define a
constant or variable to be of a function type and assign an appropriate function to that
variable:
var mathFuncti on: (Int, Int) -> Int = addT w oInts
Thi s can be read as:
“Define a variable cal led mathFuncti on, whi ch has a type of ‘a function that takes two Int
values, and returns an Int value.’ Set thi s new variable to refer to the function cal led
addT w oInts.”
The addT w oInts function has the same type as the mathFuncti on variable, and so thi s
assignment i s al lowed by Swi ft’s type-checker.
You can now cal l the assigned function wi th the name mathFuncti on:
pri ntl n("Resul t: \(mathFuncti on(2, 3))")
// pri nts "Resul t: 5"
A di fferent function wi th the same matching type can be assigned to the same variable, in
the same way as for non-function types:
mathFuncti on = mul ti pl yT w oInts
pri ntl n("Resul t: \(mathFuncti on(2, 3))")
// pri nts "Resul t: 6"
As wi th any other type, you can leave i t to Swi ft to infer the function type when you
assign a function to a constant or variable:
l et anotherMathFuncti on = addT w oInts
// anotherMathFuncti on i s i nferred to be of type (Int, Int) -> Int
## Function Types as Parameter Types
You can use a function type such as (Int, Int) -> Int as a parameter type for another
function. Thi s enables you to leave some aspects of a function’s implementation for the
function’s cal ler to provide when the function i s cal led.
Here’s an example to print the resul ts of the math functions from above:
func pri ntMathResul t(mathFuncti on: (Int, Int) -> Int, a: Int, b: Int) {
pri ntl n("Resul t: \(mathFuncti on(a, b))")
}
pri ntMathResul t(addT w oInts, 3, 5)
// pri nts "Resul t: 8"
Thi s example defines a function cal led pri ntMathResul t, whi ch has three parameters. The fi rst
parameter i s cal led mathFuncti on, and i s of type (Int, Int) -> Int. You can pass any function of
that type as the argument for thi s fi rst parameter. The second and thi rd parameters are
cal led a and b, and are both of type Int. These are used as the two input values for the
provided math function.
When pri ntMathResul t i s cal led, i t i s passed the addT w oInts function, and the integer values 3
and 5. It cal l s the provided function wi th the values 3 and 5, and prints the resul t of 8.
The role of pri ntMathResul t i s to print the resul t of a cal l to a math function of an appropriate
type. It doesn’t matter what that function’s implementation actual ly does—i t matters only
that the function i s of the correct type. Thi s enables pri ntMathResul t to hand off some of i ts
functional i ty to the cal ler of the function in a type-safe way.
## Function Types as Return Types
You can use a function type as the return type of another function. You do thi s by wri ting
a complete function type immediately after the return arrow (->) of the returning function.
The next example defines two simple functions cal led stepForw ard and stepBackw ard. The
stepForw ard function returns a value one more than i ts input value, and the stepBackw ard
function returns a value one less than i ts input value. Both functions have a type of (Int) ->
Int:
func stepForw ard(i nput: Int) -> Int {
return i nput + 1
}
func stepBackw ard(i nput: Int) -> Int {
return i nput - 1
}
Here’s a function cal led chooseStepFuncti on, whose return type i s “a function of type (Int) -> Int”.
chooseStepFuncti on returns the stepForw ard function or the stepBackw ard function based on a
Boolean parameter cal led backw ards:
func chooseStepFuncti on(backw ards: Bool ) -> (Int) -> Int {
return backw ards ? stepBackw ard : stepForw ard
}
You can now use chooseStepFuncti on to obtain a function that wi l l step in one di rection or the
other:
var currentVal ue = 3
l et moveNearerT oZero = chooseStepFuncti on(currentVal ue > 0)
// moveNearerT oZero now refers to the stepBackw ard() functi on
The preceding example works out whether a posi tive or negative step i s needed to move
a variable cal led currentVal ue progressively closer to zero. currentVal ue has an ini tial value of 3,
whi ch means that currentVal ue > 0 returns true, causing chooseStepFuncti on to return the
stepBackw ard function. A reference to the returned function i s stored in a constant cal led
moveNearerT oZero.
Now that moveNearerT oZero refers to the correct function, i t can be used to count to zero:
pri ntl n("Counti ng to zero:")
// Counti ng to zero:
w hi l e currentVal ue ! = 0 {
pri ntl n("\(currentVal ue). . . ")
currentVal ue = moveNearerT oZero(currentVal ue)
}
pri ntl n("zero! ")
// 3. . .
// 2. . .
. .
ero!
## Nested Functions
Al l of the functions you have encountered so far in thi s chapter have been examples of
global functions, whi ch are defined at a global scope. You can al so define functions inside
the bodies of other functions, known as nested functions.
Nested functions are hidden from the outside world by defaul t, but can sti l l be cal led and
used by thei r enclosing function. An enclosing function can al so return one of i ts nested
functions to al low the nested function to be used in another scope.
You can rewri te the chooseStepFuncti on example above to use and return nested functions:
func chooseStepFuncti on(backw ards: Bool ) -> (Int) -> Int {
func stepForw ard(i nput: Int) -> Int { return i nput + 1 }
func stepBackw ard(i nput: Int) -> Int { return i nput - 1 }
return backw ards ? stepBackw ard : stepForw ard
}
var currentVal ue = -4
l et moveNearerT oZero = chooseStepFuncti on(currentVal ue > 0)
// moveNearerT oZero now refers to the nested stepForw ard() functi on
w hi l e currentVal ue ! = 0 {
ri ntl n("\(currentVal ue). . . ")
urrentVal ue = moveNearerT oZero(currentVal ue)
("zero! ")
. . .
. . .
. . .
. . .
ero!
images8-1jpg

No preview for this file type

images8-2jpg

No preview for this file type

images8-3jpg

No preview for this file type