때로 는 까칠 하 게 . . : : Protocols 
 Swift / Language Guide 2018 . 09 . 18 00 : 06 
 [ 최종 수정 일 : 2018 . 09 . 05 ] 
 원문 : 애플 개발 문서 Swift 4 . 2 Language Guide - Protocols 
 프로토콜 ( protocol ) 은 특정 작업 이나 기능 적 인 부분 에 맞 는 메소드 , 프로 퍼티 , 다른 요구사항 을 상세히 ( blueprint ) 정의 합니다 . 프로토콜 은 이러 한 요구 사항 들 의 실제 구현 을 제공 하 기 위해 클래스 , 구조 체 열 거형 에 의해 채택 될 ( adopted ) 수 있 습니다 . 프로토콜 의 요구 사항 을 만족 하 는 ( satisfies ) 모든 타입 은 프로토콜 을 준 수 ( conform ) 한다고 말 합니다 . 
 요구사항 을 지정 하 는 것 외 에 도 타입 을 준 수 하 도록 반드시 구현 해야 하 며 , 이러 한 요구사항 을 구현 하 거나 추가 적 으로 준수 하 는 타입 의 함수 를 구현 하 기 위해 프로토콜 을 확장 할 수 있 습니다 . 
 프로토콜 문법 ( Protocol Syntax ) 
 클래스 , 구조 체 , 열 겨 형 과 매우 비슷 한 방법 으로 프로토콜 을 정의 합니다 . 
 사용 자정 의 타입 은 정의 하 는 곳 에서 타입 의 이름 뒤 에 콜론 ( : ) 으로 구분 해서 프로토콜 의 이름 을 위치 시켜 특정 프로토콜 을 채택 한다고 명시 합니다 . 여러 개 의 프로토콜 을 목록 화 할 수 있 고 콤마 ( , ) 로 구분 됩니다 . 
 클래스 가 상위 클래스 를 가지 고 있 는 경우 , 상위 클래스 이름 을 채택 한 프로토콜 앞 에 콤마 ( , ) 를 붙여서 나열 합니다 . 
 프로토콜 요구사항 ( Property Requirements ) 
 프로토콜 은 특정 이름 과 타입 으로 인 스턴스 프로 퍼티 나 타입 프로 퍼티 를 제공 하 기 위해 이 를 준수 하 는 모든 타입 에 요구 할 수 있 습니다 . 프로토콜 은 프로 퍼티 가 저장 프로 퍼티 ( storead property ) 인지 게 산 프로 퍼티 ( computed property ) 인지 지정 하 지 않 습니다 . - 단지 필수 프로 퍼티 이름 과 타입 만 지정 합니다 . 또한 , 프로토콜 은 각 프로 퍼티 가 gettable 또는 gettabel 과 settable 인지 를 반드시 지정 해야 합니다 . 
 프로토콜 프로 퍼티 가 gettable 과 settable 이 필요 한 경우 , 그 프로 퍼티 는 상수 저장 프로 퍼티 나 읽 기 전용 ( read - only ) 계산 프로 퍼티 로 는 요구사항 을 충족 시킬 수 없 습니다 . 프로토콜 이 gettable 이 되 는 프로 퍼티 만 요구 되 는 경우 , 모든 종류 의 프로 퍼티 에 대해 그 요구사항 을 만족 할 수 있 고 , 코드 에서 유용 한 경우 에 settable 이 되 는 프로 퍼티 에 대해서 도 유효 합니다 . 
 타입 프로 퍼티 는 프로토콜 을 정의 할 때 항상 static 키워드 를 앞 에 붙여야 합니다 . 이 규칙 은 클래스 가 구현 될 때 class 나 static 키워드 를 접두사 ( prefixed ) 로 사용 할 수 있 는 타입 프로 퍼티 요구사항 과 관련 ( pertains ) 있 습니다 . 
 다음 은 하나 의 인 스턴스 프로 퍼티 를 요구 하 는 프로토콜 의 예제 입니다 . 
 FullyName 프로토콜 을 준수 하 는 타입 이 완전 한 이름 을 제공 하 는 것 을 요구 합니다 . 프로토콜 은 준수 ( conforming ) 하 는 타입 에 대해 다른 아무것 도 지정 하 지 않 습니다 . - 이것 은 타입 이 자신 의 전체 이름 을 제공 해야 합니다 . 프로토콜 은 anyFullyName 타입 에 String 타입 의 fullName 이 라는 gettable 인 스턴스 프로 퍼티 를 반드시 가져야 합니다 . 
 다음 은 FullyNamed 프로 포 콜 을 채택 하 고 준 수 하 는 간단 한 구조 체 예제 입니다 . 
 이 예제 는 특정 이름 을 가진 사람 을 표현 하 는 구조 체 Person 을 정의 합니다 . 그것 을 정의 하 는 첫 번 째 줄 에서 FullyNamed 프로토콜 을 채택 합니다 . 
 Person 의 각 인 스턴스 는 String 타입 인 하나 의 저장 프로 퍼티 fullName 을 가지 고 있 습니다 . FullyNamed 프로토콜 의 한 개 의 요구사항 과 일치 하 고 , Person 이 그 프로토콜 을 정확히 준수 한다는 것 을 의미 합니다 . ( Swift 는 프로토콜 요구사항 이 완전 하 지 않 은 경우 에 , 컴파일 시 오류 가 납니다 . ) 
 다음 은 FullyNamed 프로토콜 을 채택 하 고 준 수 하 는 좀 더 복잡 한 클래스 입니다 . 
 이 클래스 는 fullName 프로 퍼티 요구 사항 을 우주선 ( starship ) 의 계산 읽 기 전용 프로 퍼티 로 구현 합니다 . 각 우주선 ( Starship ) 클래스 인 스턴스 는 필수 적 인 ( mandatory ) name 와 선택 적 인 ( optional ) prefix 를 저장 합니다 . fullName 프로 퍼티 는 prefix 값 이 있 은 경우 에 사용 하 고 , 우주선 에 대한 전체 이름 을 만들 기 위해 이름 의 시작 부분 에 추가 합니다 . 
 타입 프로 퍼티 요구 사항 처럼 , 프로토콜 을 정의 할 때 타입 메소드 요구사항 에 항상 static 키 둬 드 를 접두사 로 사용 합니다 . 이것 은 클 래스 를 구현 할 때 타입 메소드 요구사항 앞 에 class 나 static 키워드 를 붙일 때 에 도 마찬가지 입니다 . 
 다음 은 하나 의 인 스턴스 메소드 를 요구 하 는 프로토콜 을 정의 한 예제 입니다 . 
 RandomNumberGenerator 프로토콜 은 준수 하 는 모든 타입 에 대해 호출 될 때 마다 Double 값 을 반환 하 는 인 스턴스 메소드 random 를 요구 합니다 . 비록 프로토콜 로 지정 되 지 않 았 지만 , 이 값 이 0 . 0 부터 1 . 0 까지 의 숫자 가 될 것 이 라 가정 합니다 . 
 RandomNumberGenerator 프로토콜 을 어떻게 무작위 ( random ) 숫자 를 만들 어 내 는지 에 관여 하 지 않 습니다 - 단지 새로운 무작위 숫자 를 생성 하 는 기본 방법 을 제공 하 도록 요구 만 할 뿐 입니다 . 
 다음 은 RandomNumberGenerator 프로토콜 을 채택 ( adopts ) 하 고 준 수 ( conforms ) 하 는 클래스 구현 입니다 . 이 클래스 는 선형 합동 생성기 ( linar congruential generator ) 으로 의사 난수 ( pseudorandom ) 숫자 생성 알고리즘 을 구현 합니다 . 
 변경 하 는 메소드 요구사항 ( Mutating Method Requirements ) 
 가끔 씩 인 스턴스 에 속한 메소드 에 대해 수정 ( 또는 변경 ) 하 는 게 필요 합니다 . 값 타입 에서 인 스턴스 메소드 에 대해 이 메소드 가 인 스턴스 와 해당 인 스턴스 의 모든 프로 퍼티 를 수정 하 는 것 이 허용 된다는 것 을 가리키 기 위해 mutating 키워드 를 메소드 의 func 키워드 앞 에 위치 시킵니다 . 이 처리 과정 은 인 스턴스 메소드 에서 값 타입 수정 하 기 ( Modifying Value Types from Within Instance Methods ) 에 설명 되 어 있 습니다 . 
 프로토콜 을 채택 한 모든 타입 의 인 스턴스 를 변경 하 기 위해 프로토콜 인 스턴스 메소드 요구사항 을 정의 하 는 경우 에 , 그 메소드 는 프로토콜 의 정의 에서 mutating 키워드 로 표시 합니다 . 이것 은 구조 체 와 열 거형 이 프로토콜 을 채택 하 고 메소드 요구사항 을 만족 ( satisfy ) 하 는 것 을 가능 하 게 합니다 . 
 프로토콜 인 스턴스 메소드 요구사항 을 mutating 으로 표시 하 는 경우 , 클래스 에 대한 메소드 의 구현 에 mutating 키워드 를 작성 할 필요 가 없 습니다 . mutating 키워드 는 구 조체 나 열거 형 에서 만 사용 됩니다 . 
 아래 예제 는 하나 의 인 스턴스 메소드 toggle 요구사항 이 있 는 프로토콜 Togglable 을 정의 합니다 . 이름 에서 알 수 있 듯이 , toggle ( ) 메소드 는 모든 준수 하 는 타입 의 상태 를 토글 ( toggle ) 하 거나 상태 를 반전 ( invertd ) 을 의도 하 며 , 일반 적 으로 타입 의 프로 퍼티 를 수정 합니다 . 
 toggle ( ) 메소드 는 Toggleable 프로토콜 정의 에서 mutating 키워드 로 표시 되 며 , 그 메소드 는 호출 될 때 준수 하 는 인 스턴스 의 상태 를 변경 할 수 있 는 게 예상 됩니다 . 
 구 조체 나 열거 형 에 대한 Togglable 프로토콜 을 구현 하 는 경우 , 그 구조 체 나 열거 형 은 mutating 으로 표시 된 toggle ( ) 메소드 구현 을 제공 하 여 프로 콜 을 준 수 할 수 있 습니다 . 
 아래 예제 는 열거 형 OnOffSwitch 를 정의 합니다 . 이 열 거형 은 두 가지 상태 를 토글 하 며 , 열거 형 케이스 on 과 off 를 가리킵니다 . 열 거형 의 toggle 구현 은 mutating 으로 구현 되 고 , Toggleable 프로토콜 의 요구사항 과 일치 합니다 . 
 초기 화 요구사항 
 프로토콜 은 준수 하 는 타입 에게 특정 초기 화 구현 을 요구 할 수 있 습니다 . 일반 적 인 초기 화 와 정확히 같 은 방법 으로 프로토콜 의 정의 에서 이러 한 초기 화 를 작성 할 수 있 지만 , 중괄호 와 초기 화 본문 은 없 습니다 . 
 프로토콜 초기 화 요구사항 의 클래스 구현 ( Class Implementations of Protocol Initializer Requirements ) 
 지정 된 초기 화 나 편리 한 초기 화 처럼 , 이 를 준수 하 는 클래스 에서 프로토콜 초기 화 요구 사항 을 구현 할 수 있 습니다 . 두 경우 모두 , 반드시 초기 화 구현 에 required 수식어 를 표시 해야 합니다 . 
 required 수식어 를 사용 하 는 것 은 이 를 준수 하 는 클래스 의 모든 하위 클래스 에서 명시 적 으로 제공 하 거나 초기 화 요구사항 의 구현 하 는 것 을 보장 합니다 . 
 필요 한 초기 화 에 대한 자세 한 정보 는 , 필요 한 초기 화 ( Required Initializers ) 를 보 세요 . 
 final 클래스 는 하위 클래스 를 사용 할 수 없 기 때문 에 , final 수식어 로 표시 된 클래스 에서 는 프로토콜 초기 화 구현 에 required 수식어 를 표시 하 는 게 필요 하 지 않 습니다 . final 수식어 에 대한 자세 한 정보 는 오버 라이드 막기 ( Preventing Overrides ) 를 보 세요 . 
 하위 클래스 가 상위 클래스 의 지정 된 초기 화 를 오버 라 이 딩 하 는 경우 에 , 프로토콜 의 초기 화 요구사항 과 일치 하 도록 구현 하 며 , required 와 override 수식어 모두 초기 화 구현 에 표시 합니다 . 
 실패 할 수 있 는 초기 화 요구사항 ( Failable Initializer Requirements ) 
 실패 할 수 있 는 초기 화 ( Failable Initializers ) 에 정의 된 것 처럼 , 프로토콜 은 준수 하 는 타입 에 대해 실패 할 수 있 는 초기 화 요구 사항 을 정의 할 수 있 습니다 . 
 실패 할 수 있 는 초기 화 요구사항 은 준수 하 는 타입 에서 실패 할 수 있 거나 ( faiable ) 실패 하 지 않 는 ( nonfailable ) 초기 화 를 만족 할 수 있 습니다 . 실패 하 지 않 는 ( nonfailable ) 초기 화 요구사항 은 실패 하 지 않 는 초기 화 또는 암시 적 으로 언 래핑 된 ( unwrapped ) 실패 할 수 있 는 ( failable ) 초기 화 로 만족 할 수 있 습니다 . 
 타입 같 은 프로토콜 ( Protocols as Types ) 
 프로토콜 은 실제 어떤 함수 도 구현 하 지 않 습니다 . 그럼에도 불구 하 고 , 모든 프로토콜 은 코드 에서 사용 하 는 완벽 한 타입 이 될 것 입니다 . 
 프로토콜 도 타입 이 기 때문 에 , 프로토콜 을 다른 타입 이 허용 되 는 많 은 곳 에서 사용 할 수 있 습니다 . 
 함수 , 메소드 , 초기 화 에서 매개변수 타입 이나 반환 타입 
 배열 , 딕셔너리 , 다른 컨테이너 에서 항목 들 의 타입 
 프로토콜 은 타입 이 기 때문 에 , Swift 에서 의 다른 타입 의 이름 과 같이 ( Int , String , Double ) 이름 을 대문자 로 ( FullyNamed , RandomNumberGenerator ) 시작 합니다 . 
 다음 은 프로토콜 을 타입 으로 사용 하 는 예제 입니다 . 
 이 예제 는 보드게임 에서 사용 하 는 n 면 의 주사위 를 표현 하 는 새로운 클래스 Dice 를 정의 합니다 . Dice 인 스턴스 는 얼마나 많 은 면 을 가지 는지 를 나타내 는 정수 형 프로 퍼티 sides 와 생성 한 주사위 를 던진 값 을 무작위 로 생성 하 는 프로 퍼티 generator 를 가집니다 . 
 generator 프로 퍼티 는 RandomNumberGenerator 타입 입니다 . 그러므로 , RandomNumberGenerator 프로토콜 을 채택 한 모든 ( any ) 타입 의 인 스턴스 에 설정 할 수 있 습니다 . 이 프로 퍼피 에 할당 된 인 스턴스 에 는 RandomNumberGenerator 프로토콜 을 채택 해야 하 는 것 을 빼 고 다른 것 은 필요 하 지 않 습니다 . 
 또한 , Dice 는 초기 상태 를 설정 하 기 위한 초기 화 를 가지 고 있 습니다 . 이 초기 화 는 RandomNumberGenerator 타입 인 매개변수 generator 를 가집니다 . 새로운 Dice 인 스턴스 를 초기 화 할 때 이 매개변수 에 모든 준수 하 는 타입 의 값 을 전달 할 수 있 습니다 . 
 Dice 는 1 과 주사위 면 의 숫자 사이 의 정수 형 값 을 반환 하 는 인 스턴스 메소드 roll 를 제공 합니다 . 이 메소드 는 0 . 0 과 1 . 0 사이 의 새로운 무작위 숫자 를 생성 하 고 이 무작위 숫자 를 주사위 를 던지 는 정확 한 범위 의 값 으로 생성 하 기 위해 생성기 ( generator ) 의 random ( ) 메소드 를 호출 합니다 . generator 은 RandomNumberGenerator 을 채택 한 것 으로 알려져 있 기 때문 에 , 호출 할 random ( ) 메소드 가 있 어야 합니다 . 
 다음 은 Dice 클래스 가 무작위 숫자 를 생성 하 는 L i nearCongruentialGenerator 인 스턴스 로 6 면 의 주사위 를 만들 어 사용 하 는 방법 입니다 . 
 위임 ( delegation ) 은 클래스 나 구조 체가 다른 타입 의 인 스턴스 에게 책임 을 넘겨 주 는 ( hand off 또는 delegate ) 것 이 가능 한 디자인 패턴 입니다 . 이 디자인 패턴 은 준수 하 는 타입 이 위임 된 기능 을 제공 하 는 것 을 보장 하 는 것 처럼 , 위임 된 책임 을 캡슐 화 하 는 프로토콜 을 정의 해서 구현 됩니다 . 위임 은 특정 동작 의 응답 하 는 데 사용 될 수 있 거나 소스 의 기본 타입 과 상관 없이 외부 소스 로부터 데이터 를 검색 하 는 데 사용 할 수 있 습니다 . 
 아래 예제 는 주사위 기반 의 보드게임 에서 사용 하 는 프로토콜 2 개 를 정의 합니다 
 DiceGame 프로토콜 은 주사위 와 관련 있 는 모든 게임 으로 채택 ( adopted ) 될 수 있 는 프로토콜 입니다 . 
 DiceGameDelegate 프로토콜 은 DiceGame 의 진행 을 추적 하 기 위해 채택 될 수 있 습니다 . 강한 순환 참조 ( strong reference cycles ) 를 막 기 위해 , 위임자 ( delegates ) 는 약한 참조 ( weak references ) 로 선언 됩니다 . 약한 참조 에 대한 자세 한 정보 는 클래스 인 스턴스 간 에 강한 순한 참조 ( Strong Reference Cycles Between Class Instances ) 를 보 세요 . 프로토콜 을 클 래스 전용 으로 만들 어 이 챕터 의 마지막 에 있 는 SnakesAndLadders 클래스 에서 해당 위임자 ( delegate ) 가 반드시 약한 참조 를 사용 하 도록 선언 할 수 있 습니다 . 클래스 전용 프로토콜 ( Class - Only Protocols ) 에서 논의 된 것 처럼 클래스 전용 프로토콜 은 AnyObject 로 부 터 의 상속 을 표시 합니다 . 
 다음 은 흐름 제어 ( Control Flow ) 에서 처음 ( orignally ) 소개 된 뱀 과 사다리 ( Snakes and Ladders ) 게임 의 버 젼 입니다 . 이 버 젼 은 주사위 를 던지 기 ( dice - rolls ) 위해 , DiceGame 프로토콜 을 적용 하 기 위해 , 그리고 DiceGameDelegate 에 진행 상황 을 알리 기 위해 , Dice 인 스턴스 가 채택 되 었 습니다 . 
 뱀 과 사다리 ( Snakes and Ladders ) 게임 진행 에 대해서 는 , Break 를 보 세요 . 
 이 게임 의 버 젼 은 DiceGame 프로토콜 을 채택 한 SnakesAndLadders 으로 래핑 ( wrapped ) 되 었 습니다 . 프로토콜 을 준수 하 기 위해 gettable dice 프로 퍼티 와 play ( ) 메소드 를 제공 합니다 . ( dice 프로 퍼티 는 초기 화 이후 에 변경 할 필요 가 없 기 때문 에 , 상수 프로 퍼티 로 선언 되 고 , 프로토콜 은 gettable 만 요구 합니다 ) 
 뱀 과 사다리 ( Snakes and Ladders ) 보드 게임 은 클래스 의 init ( ) 초기 화 에서 설정 합니다 . 모든 게임 로직 은 주사위 던지 는 값 을 제공 하 기 위해 프로토콜 의 요구 사항 인 dice 프로 퍼티 를 사용 하 는 , 프로토콜 의 play 메소드 로 이동 됩니다 . 
 delegate 이 게임 플레이 에서 필수 사항 이 아니 기 때문 에 , delegate 프로 퍼티 가 옵 셔 널 ( optional ) DiceGameDelegate 로 정의 된 것 을 주의 합니다 . 옵 셔 널 타입 이 기 때문 에 , delegate 프로 퍼티 는 자동 으로 초기 값 으로 nil 을 설정 합니다 . 그 후 에 , 게임 인 스턴스 는 프로 퍼티 를 적절 한 위임자 ( delegate ) 로 설정 할 수 있 습니다 . DiceGameDelegate 프로토콜 은 클래스 전용 ( class - only ) 이 기 때문 에 , 위임자 ( delegate ) 를 순환 참조 를 막 기 위해 weak 가 되 도록 선언 할 수 있 습니다 . 
 DiceGameDelegate 는 게임 의 진행 을 추적 하 는 3 개 의 메소드 를 제공 합니다 . 이러 한 3 개 의 메소드 는 위 의 play ( ) 메소드 에 게임 로직 안 으로 통합 ( incorporated ) 되 고 , 새 게임 을 시작 할 때 호출 되 며 , 새로운 턴 ( turn ) 이 시작 하 거나 게임 이 끝납니다 . 
 delegate 프로 퍼티 는 옵 셔 널 ( optional ) DiceGameDelegate 이 기 때문 에 , play ( ) 메소드 는 위임자 ( delegate ) 에서 메소드 가 호출 될 때 마다 옵 셔 널 체 이닝 을 사용 합니다 . delegate 프로 퍼티 가 nil 인 경우 에 , 이 위임자 ( delegate ) 호출 은 오류 없이 우아 하 게 실패 할 것 입니다 . delegate 프로 퍼티 가 non - nil 인 경우 에 , 위임자 ( delegate ) 메소드 는 호출 되 고 , 매개변수 로 SnakesAndLadders 인 스턴스 가 전달 될 것 입니다 . 
 다음 예제 는 DiceGameDelegate 프로토콜 을 채택 한 클래스 DiceGameTracker 를 보여 줍니다 . 
 DiceGameTracker 는 DiceGameDelegate 의 요구 사항 인 3 개 의 메소드 모두 구현 합니다 . 이 메소드 들 은 게임 의 턴 수 를 기록 하 는 데 사용 합니다 . 게임 을 시작 할 때 , numberOfTurns 프로 퍼티 는 0 으로 재 설정 하 며 , 새로운 턴 이 시작 할 때 마다 증가 시키 고 , 게임 이 종료 되 면 전체 턴 의 개수 를 출력 합니다 . 
 위 에서 보여준 gameDidStart ( _:) 의 구현 은 시작 된 게임 을 소개 하 는 정보 를 출력 하 기 위해 game 매개변수 를 사용 합니다 . game 매개변수 는 SnakesAndLadders 가 아닌 , DiceGame 타입 이 고 gameDidStart ( _:) 를 사용 할 수 있 고 DiceGame 프로토콜 로 구현 된 메소드 와 프로 퍼티 만 사용 할 수 있 습니다 . 하지만 , 이 메소드 는 여전히 기본 인 스턴스 타입 을 조회 하 기 위해 타입 변환 이 가능 합니다 . 이 예제 에서 , game 이 실제 SnakesAndLadders 의 인 스턴스 인지 검사 하 고 , 적절 한 메시지 를 출력 합니다 . 
 gameDidStart ( _:) 메소드 는 game 매개변수 로 전달 된 dice 프로 퍼티 에 접근 합니다 . game 이 DiceGame 프로토콜 을 준수 하 는 것 으로 알 고 있 기 때문 에 , dice 프로 퍼티 가 있 는 것 을 보장 하 고 , gameDidStart ( _:) 메소드 는 어떤 게임 의 종류 인지 상관없이 ( regardless ) , 주사위 의 sides 프로 퍼티 에 접근 하 고 출력 이 가능 합니다 . 
 다음 은 DiceGameTracker 가 동작 하 는 방법 입니다 . 
 확장 으로 프로토콜 준수 하 도록 추가 하 기 ( Adding Protocol Conformance with an Extension ) 
 기존 타입 에 대한 소스 코드 접근 이 없 는 경우 에 도 , 새로운 프로토콜 을 채택 ( adopt ) 하 고 준 수 ( conform ) 해서 기존 타입 을 확장 할 수 있 습니다 . 확장 ( Extensions ) 은 기존 타입 에 새로운 프로 퍼티 , 메소드 , 서브 스크립트 를 추가 할 수 있 고 , 프로토콜 이 요구 사항 을 추가 하 는 것 이 가능 합니다 . 확장 에 대한 자세 한 정보 는 확장 ( Extensions ) 를 보 세요 . 
 타입 의 기존 인 스턴스 는 확장 에서 인 스턴스 의 타입 에 준수 하 도록 프로토콜 을 이 추가 될 때 , 프로토콜 은 자동 으로 채택 되 고 준 수 하 게 됩니다 . 
 예 를 들 어 , 프로토콜 TextRepresentable 은 텍스트 롤 표현 할 수 있 는 모든 타입 으로 구현 될 수 있 습니다 . 이 는 스스로 에 대한 설명 이 거나 현재 상태 의 텍스트 버 젼 일 수 있 습니다 . 
 위 의 Dice 클래스 는 TextRepresentable 을 채택 하 고 준 수 하 여 확장 될 수 있 습니다 . 
 모든 Dice 인 스턴스 는 이제 TextRepresentable 를 처리 할 수 있 습니다 . 
 비슷 하 게 , SnakesAndLadders 게임 클래스 는 TextRepresentable 프로토콜 을 채택 하 고 준 수 하 도록 확장 될 수 있 습니다 . 
 조건부 로 프로토콜 준수 하 기 ( Conditionally Conforming to a Protocol ) 
 제네릭 타입 은 타입 의 제네릭 매개변수 가 프로토콜 을 준 수 할 때 , 프로토콜 의 요구 사항 을 특정 조건 에서 만 만족 하 는 게 가능 할 것 입니다 . 타입 을 확장 할 때 제약 조건 ( constraints ) 을 나열 하 여 ( listing ) , 제네릭 타입 이 프로토콜 을 조건부 준수 하 도록 만들 수 있 습니다 . 이러 한 제약 조건 은 제네릭 where 절 을 채택 ( adopting ) 하 는 프로토콜 의 이름 뒤 에 작성 합니다 . 제네릭 where 절 에 대한 자세 한 것 은 제네릭 Where 절 ( Generic Where Clauses ) 를 보 세요 . 
 다음 에 오 는 확장 은 TextRepresentable 을 준수 하 는 타입 의 요소 들 을 저장 할 때 마다 , Array 인 스턴스 가 TextRepresentable 프로토콜 을 준 수 하 도록 만듭니다 . 
 확장 으로 프로토콜 채택 선언 하 기 ( Declaring Protocol Adoption with an Extension ) 
 타입 이 프로토콜 의 모든 요구사항 을 이미 준수 하 지만 , 프로토콜 을 아직 채택 하 지 않 은 경우 , 비 어 있 는 확장 으로 프로토콜 을 채택 하 도록 만들 수 있 습니다 . 
 이제 Hamster 의 인 스턴스 는 TextRepresentable 이 요구 된 타입 일 때 마다 사용 될 수 있 습니다 . 
 타입 은 요구사항 을 만족 하 더라도 프로토콜 을 자동 으로 채택 하 지 않 습니다 . 프로토콜 을 채택 하 는 것 에 대해 항상 명시 적 으로 선언 해 줘야 합니다 . 
 프로토콜 타입 모음 ( Collections of Protocol Type ) 
 타입 같 은 프로토콜 ( Protocols as Types ) 에서 언급 했 던 것 처럼 , 프로토콜 은 배열 이나 딕셔너리 처럼 , 컬렉션 ( collection ) 에 저장 되 도록 타입 처럼 사용 될 수 있 습니다 . 이 예제 는 TextRepresentable 의 배열 을 생성 합니다 . 
 이제 배열 내 의 항목 들 을 반복 하 고 , 각 항목 들 의 텍스트 설명 을 출력 하 는 게 가능 합니다 . 
 thing 상수 는 TextRepresentable 타입 인 것 을 주의 합니다 . 그것 은 Dice 나 DiceGame , Hamster 타입 이 아니 며 , 심지어 는 , 실제 인 스턴스 가 이러 한 타입 중 하나 일 지라도 말 입니다 . 그럼에도 불구 하 고 , TextRepresentable 타입 이 기 때문 에 , TextRepresentable 이 가지 고 있 는 것 으로 알 고 있 는 textualDescription 프로 퍼티 를 반 복문 을 통해서 매번 thing . textualDescription 을 안 전하 게 접근 할 수 있 습니다 . 
 프로토콜 은 하나 이상 의 다른 프로토콜 을 상속 ( inherit ) 할 수 있 고 상속 한 요구사항 보다 더 많 은 요구사항 을 추가 할 수 있 습니다 . 프로토콜 상 속 에 대한 문법 은 클래스 상 속 에 대한 문법 과 비슷 하 지만 , 상속 된 여러 프로토콜 들 을 콤마 ( , ) 로 구분 해서 나열 하 는 옵션 이 있 습니다 . 
 다음 은 위 의 TextRepresentable 프로토콜 을 상속 하 는 프로토콜 의 예제 입니다 . 
 이 예제 는 TextRepresentable 로 부 터 상속 받 은 새로운 프로토콜 PrettyTextRepresentable 을 정의 합니다 . PrettyTextRepresentable 을 채택 한 것 들 은 반드시 TextRepresentable 에 의해 강제 된 요구사항 모두 를 만족 해야 하 며 , PrettyTextRepresentable 에 의해 강요된 요구사항 이 추가 적 인 으로 더 해집니다 ( plus ) . 이 예제 에서 , PrettyTextRepresentable 은 String 을 반환 하 는 gettable 프로 퍼티 prettyTextualDescription 을 제공 하 기 위한 요구사항 하나 를 추가 합니다 . 
 SnakesAndLadders 클래스 는 PrettyTextRepresentable 을 채택 하 고 준 수 하 도록 확장 될 수 있 습니다 . 
 이 확장 상태 는 PrettyTextRepresentable 프로토콜 을 채택 하 고 SnakesAndLadders 타입 에 대한 prettyTextualDescription 프로 퍼티 구현 을 제공 합니다 . 모든 PrettyTextRepresentable 은 TextRepresentable 이 되 어야 하 고 , 문자열 출력 을 시작 하 기 위한 prettyTextualDescription 의 구현 은 TextRepresentable 프로토콜 로부터 textualDescription 프로 퍼티 를 접근 해서 시작 합니다 . 콜론 ( : ) 과 줄 바꿈 ( line break ) 을 추가 하 고 , 텍스트 를 보 기 좋 게 ( pretty ) 표현 하 는 것 으로 시작 합니다 . 그런 다음 보드 판 의 배열 을 반복 하 고 , 각 칸 ( square ) 의 콘텐츠 를 표현 하 기 위한 특수 문자 를 추가 합니다 . 
 칸 ( square ) 의 값 이 0 보다 큰 경우 , 사다리 의 시작 이 고 , ▲ 으로 표현 됩니다 . 
 칸 ( square ) 의 값 이 0 보다 작 은 경우 , 뱀 의 머리 이 고 , ▼ 으로 표현 됩니다 . 
 그 외 에 , 칸 ( square ) 의 값 이 0 이 고 , 비 어 있 는 ( free ) 칸 이 며 , ○ 으로 표현 됩니다 . 
 이제 prettyTextualDescription 프로 퍼티 는 모든 SnakesAndLadders 인 스턴스 의 텍스트 설명 을 보 기 좋 게 출력 하 는 데 사용 됩니다 . 
 위 의 예제 에서 , SomeClassOnlyProtocol 은 클래스 타입 에서 만 채택 될 수 있 습니다 . 구 조체 나 열거 형 정의 에 SomeClassOnlyProtocol 을 적용 하 려고 하 면 컴파일 시 오류 가 발생 합니다 . 
 준수 하 는 타입 이 값 의 의미 보다 는 참조 의 의미 를 가지 는 프로토콜 의 요구 사항 을 가정 하 거나 요구 에 의한 동작 을 정의 할 때 클래스 전용 ( class - only ) 프로토콜 을 사용 합니다 . 참조 와 값 의 의미 에 대한 자세 한 것 은 구조 체 와 열 거형 은 값 타입 ( Structures and Enumerations Are Value Types ) 과 클래스 는 참조 타입 ( Classes Are Reference Types ) 를 보 세요 . 
 프로토콜 합성 ( Protocol Composition ) 
 그것 은 한 번 에 여러 개 의 프로토콜 을 준 수 하 도록 타입 에 요구 할 때 유용 할 수 있 습니다 . 여러 개 의 프로토콜 을 프로토콜 합성 ( protocol composition ) 으로 하나 의 요구사항 으로 결합 시킬 수 있 습니다 . 프로토콜 합성 ( compositions ) 은 합성 안 에 모든 프로토콜 의 요구사항 이 결합 된 임시 로컬 프로토콜 로 정의 된 것 처럼 동작 합니다 . 프로토콜 합성 은 새로운 프로토콜 타입 을 정의 하 지 않 습니다 . 
 프로토콜 합성 은 SomeProtocol & AnotherProtocol 형식 을 가집니다 . 필요 한 만큼 의 프로토콜 을 나열 할 수 있 으며 , & 로 구분 합니다 . 프로토콜 의 목록 외 에 도 , 프로토콜 합성 은 필요 한 상위 클래스 를 지정 하 기 위해 , 클래스 타입 을 포함 할 수 있 습니다 . 
 다음 은 함수 의 매개변수 에서 2 개 의 프로토콜 Named 와 Aged 를 하나 의 프로토콜 합성 요구 사항 으로 결합 한 예제 입니다 . 
 또한 , 그 예 제 는 wishHappyBirthday ( to : ) 함수 를 정의 합니다 . celebrator 매개변수 의 타입 은 모든 타입 은 Named 와 Aged 프로토콜 을 준수 합니다 를 의미 하 는 Named & Aged 입니다 . 필요 한 프로토콜 모두 를 준수 하 는 한 , 특정 타입 이 함수 로 전달 되 는 것 은 중요 하 지 않 습니다 . 
 beginConcert ( in : ) 함수 는 모든 타입 은 Location 의 하위 클래스 이 고 Named 프로토콜 을 준수 합니다 을 의미 하 는 Location & Named 타입 의 매개변수 를 가집니다 . 이 경우 에 는 , City 는 모든 요구사항 을 만족 합니다 . 
 프로토콜 을 준 수 하 는지 확인 하 기 ( Checking for Protocol Conformance ) 
 프로토콜 을 준 수 하 는지 검사 하 기 위해 타입 변환 ( Type Casting ) 에서 설명 된 is 와 as 연산자 를 사용 할 수 있 고 , 특정 프로토콜 을 변환 할 수 있 습니다 . 프로토콜 을 확인 하 고 변환 하 는 것 은 타입 을 검사 하 고 변환 화 는 것 과 정확히 같 은 문법 입니다 . 
 인 스턴스 가 프로토콜 을 준수 하 는 경우 에 is 연산자 는 true 를 반환 하 고 , 그렇 지 않 으면 , false 를 반환 합니다 . 
 다운 캐스트 연산자 의 버 젼 인 as ? 는 프로토콜 타 읩의 옵 셔 널 값 을 반환 하 고 , 그 인 스턴스 가 프로토콜 을 준 수 하 지 않 는 경우 에 , 이 값 이 nil 입니다 . 
 강제 다운 캐스트 연산자 버 젼 인 as ! 는 프로토콜 타입 을 다운 케스 트 하 고 다운 캐스트 가 성공 하 지 않 으면 런타임 오류 가 발생 합니다 . 
 이 예제 는 하나 의 프로 퍼티 gettable Double 프로 퍼티 area 를 요구 하 는 프로토콜 HasArea 를 정의 합니다 . 
 Circle 클래스 는 저장 프로 퍼티 radius 를 기반 으로 계산 프로 퍼티 처럼 area 프로 퍼티 요구 사항 을 구현 합니다 . Country 클래스 구현 은 저장 프로 퍼티 처럼 직접 area 요구 사항 을 구현 합니다 . 두 클 래스 모두 HasArea 프로토콜 을 정확히 준수 합니다 . 
 다음 은 HasArea 프로토콜 을 준 수 하 지 않 는 , Animal 클래스 입니다 . 
 Circle , Country , Animal 클래스 는 기본 클래스 를 공유 하 지 않 습니다 . 그럼에도 불구 하 고 모든 클래스 와 이러 한 모든 타입 의 인 스턴스 는 AnyObject 타입 의 값 을 저장 하 는 배열 을 초기 화 하 는 데 사용 될 수 있 습니다 . 
 objects 배열 은 반지름 이 2 인 Circle 인 스턴스 , 영국 의 면적 을 평방 킬로미터 로 초기 화 된 Country 인 스턴스 , 3 개 의 다리 를 가진 Animal 인 스턴스 를 포함 하 는 배열 리터럴 로 초기 화 됩니다 . 
 objects 배열 은 이제 반복 할 수 있 고 , 배열 내 의 각 객체 ( object ) 를 검사 하 여 HasArea 프로토콜 을 준 수 하 는지 확인 할 수 있 습니다 . 
 배열 내 의 객체 가 HasArea 프로토콜 을 준 수 할 때 마다 , as ? 연산자 에 의해 반환 되 는 옵 셔 널 값 은 옵 셔 널 바인딩 을 사용 하 여 objectWithArea 상수 로 언 래핑 됩니다 . objectWithArea 상수 는 HasArea 타입 이 되 고 , area 프로 퍼티 는 타입 에 안 전하 게 ( type - safe ) 접근 하 고 출력 될 수 있 습니다 . 
 기본 객체 는 변환 ( casting ) 과정 에서 변경 되 지 않 는 것 을 주의 합니다 . 그것 들 은 Circle , Country , animal 이 될 수 있 습니다 . 하지만 , 이 시점 에 , 그것 들 은 objectWithArea 상수 에 저장 되 며 , HasArea 타입 이 되 는 것 을 알 고 있 고 , area 프로 퍼티 에 만 접근 할 수 있 습니다 . 
 옵 셔 널 프로토콜 요구사항 ( Optional Protocol Requirements ) 
 프로토콜 에 대한 프로 콜 에 대한 옵 셔 널 요구사항 ( optional requirements ) 을 정의 할 수 있 습니다 . 이러 한 요구 사항 들 은 프로토콜 을 준수 하 는 타입 에 의해 구현 할 필요 가 없 습니다 . 옵 셔 널 요구사항 은 프로토콜 정의 에서 optional 수식어 를 접두사 로 붙입니다 . 옵 셔 널 요구사항 은 Objective - C 와 상호 호환 ( interoperates ) 되 는 코드 를 작성 하 는 것 이 가능 합니다 . 프로토콜 과 옵 셔 널 요구사항 은 반드시 @ objc 속성 으로 표시 되 어야 합니다 . @ objc 프로토콜 은 Objective - C 클래스 나 다른 @ objc 클래스 를 상속 하 는 클래스 에서 만 채택 될 수 있 는 것 을 주의 합니다 . 구 조체 나 열거 형 에서 는 채택 할 수 없 습니다 . 
 옵 셔 널 요구사항 에서 메소드 나 프로 퍼티 를 사용 할 때 , 그 타입 은 자동 적 으로 옵 셔 널 이 됩니다 . 예 를 들 어 , ( Int ) -> String 타입 의 메소드 는 ( ( Int ) -> String ) ? 이 됩니다 . 함수 타입 은 메소드 의 반환 값 이 아니 라 전체 가 옵 셔 널 로 랩 핑 ( wrapped ) 되 는 것 을 주의 합니다 . 
 옵 셔 널 프로토콜 요구사항 은 프로토콜 을 준수 하 는 타입 으로 요구사항 이 구현 되 지 않 을 가능 성 을 가정 하 기 위해 , 옵 셔 널 체 이닝 으로 호출 될 수 있 습니다 . someOptionalMethod ? ( someArgument ) 처럼 , 메소드 가 호출 될 때 메소드 의 이름 뒤 에 물음표 ( ? ) 를 작성 하 여 옵 셔 널 메소드 의 구현 에 대해 검사 합니다 옵 셔 널 체 이닝 에 대한 자세 한 정보 는 옵 셔 널 체 이닝 ( Optional Chaining ) 을 보 세요 . 
 다음 에 오 는 예제 는 외부 데이터 소스 로 양 을 증가 시키 는 데 사용 하 는 정수 계산 ( integer - counting ) 클래스 Counter 를 정의 합니다 . 이 데이터 소스 는 2 개 의 옵 셔 널 요구사항 을 가진 CounterDataSource 프로토콜 에 의해 정의 됩니다 . 
 CounterDatasource 프로토콜 은 옵 셔 널 메소드 요구사항 increment ( forCount : ) 와 옵 셔 널 프로 퍼티 요구사항 fixedIncrement 를 정의 합니다 . 이러 한 요구 사항 들 은 Counter 인 스턴스 에 대한 양 을 적절히 증가 하 는 것 을 제공 하 기 위해 , 데이터 소스 에 대해 2 가지 다른 방법 을 정의 합니다 . 
 엄밀히 말 하 면 , 어떠 한 ( either ) 프로토콜 요구사항 구현 없이 CounterDataSource 를 준수 하 는 사용 자정 의 클래스 를 작성 할 수 있 습니다 . 그것 들 은 결국 모두 옵 셔 널 입니다 . 비록 기술 적 으로 가능 하 지만 , 아주 좋 은 데이터 소스 를 만들 지 는 못 합니다 . 
 아래 에 정의 된 Counter 클래스 는 CounterDataSource ? 타입 의 옵 셔 널 dataSource 프로 퍼티 를 가집니다 . 
 Counter 클래스 는 변수 프로 퍼티 count 에 현재 값 을 저장 합니다 . 또한 , Counter 클래스 는 메소드 가 호출 될 때 마다 count 프로 퍼티 를 증가 시키 는 메소드 increment 를 정의 합니다 . 
 increment ( ) 메소드 는 처음 에 데이터 소스 로부터 increment ( forCount : ) 메소드 의 구현 으로 조회 하 여 증가 한 값 을 가져오 도록 시도 합니다 . increment ( ) 메소드 는 increment ( forCount : ) 호출 하 기 위해 옵 셔 널 체 이닝 을 사용 하 고 , 메소드 의 단일 인자 로 현재 count 값 을 전달 합니다 . 
 옵 셔 널 체 이닝 의 2 ( two ) 단계 가 여기 에서 수행 되 는 것 을 주의 합니다 . 첫 번 째 , dataSource 가 nil 이 될 가능 성 이 있 고 , dataSource 가 nil 이 아닌 경우 에 만 , dataSource 가 increment ( forCount : ) 를 호출 하 는 것 을 가리키 기 위해 이름 뒤 에 물음표 를 가집니다 . 두 번 째 , dataSource 가 있 는 경우 , 옵 셔 널 요구사항 이 기 때문 에 , increment ( forCount : ) 구현 을 보장 하 지 않 습니다 . 여기 에서 , 옵 셔 널 체 이닝 에 의해 처리 되 어 increment ( forCount : ) 는 구현 되 지 않 을 수 있 습니다 . increment ( forCount : ) 가 존재 하 는 경우 에 만 ( nil 이 아닌 경우 ) , increment ( forCount : ) 가 호출 이 발생 합니다 . . 이것 이 increment ( forCount : ) 가 이름 뒤 에 물음표 ( ? ) 로 작성 되 는 이유 입니다 . 
 increment ( forCount : ) 호출 은 두 가지 이유 로 실패 할 수 있 기 때문 에 , 그 호출 은 옵 셔 널 ( optional ) Int 값 입니다 . CounterDataSource 의 정의 에서 increment ( forCount : ) 이 옵 셔 널 이 아닌 Int 값 을 반환 하 는 것 으로 정의 됩 어 있 어도 마찬가지 입니다 . 2 개 의 옵 셔 널 체 이닝 동작 이 있 으며 , 하나 씩 , 그 결과 는 여전히 하나 의 옵 셔 널 로 랩 핑 ( wrapped ) 됩니다 . 여러 개 의 옵 셔 널 체 이닝 동작 을 사용 하 는 것 에 관한 자세 한 정보 는 체 이닝 의 여러 단계 연결 하 기 ( Linking Multiple Levels of Chaining ) 을 보 세요 . 
 increment ( forCount : ) 호출 한 이후 에 , 반환 하 는 옵 셔 널 Int 는 옵 셔 널 바인딩 을 사용 하 여 , 상수 amount 로 언 래핑 됩니다 . 옵 셔 널 Int 가 값 ( 위임자 ( delegate ) 와 메소드 ( method ) 모두 존재 하 는 경우 , 메소드 가 반환 한 값 ) 을 포함 하 는 경우 , 언 래핑 된 amount 는 저장 프로 퍼티 count 에 추가 되 고 , 증가 하 는 것 이 완료 됩니다 . 
 increment ( forCount : ) 메소드 로부터 값 을 가져오 는 게 가능 하 지 않 은 경우 ( datasource 가 nil 이 거나 데이터 소스 가 increment ( forCount : ) 구현 하 지 않 았 기 때문 ) , increment ( ) 메소드 는 데이터 소스 의 fixedIncrement 프로 퍼티 대신 하 여 값 을 가져오 려고 시도 합니다 . fixedIncrement 프로 퍼티 는 옵 셔 널 요구사항 이 며 , 그 값 은 옵 셔 널 Int 값 이 며 , fixedIncrement 는 CounterDataSource 프로토콜 정의 에서 옵 셔 널 이 아닌 Int 프로 퍼티 로 정의 되 어 있 습니다 . 
 다음 은 간단 하 게 조회 할 때 마다 3 의 상수 값 을 반환 하 는 데이터 소스 CounterDataSource 를 구현 하 였 습니다 . 그것 은 옵 셔 널 fixedIncrement 프로 퍼티 요구 사항 을 구현 하 여 수행 합니다 . 
 새로운 Counter 인 스턴스 에 대한 데이터 소스 로 ThreeSource 의 인 스턴스 를 사용 할 수 있 습니다 . 
 위 코드 는 새로운 Counter 인 스턴스 를 생성 합니다 . 데이터 소스 에 새로운 ThreeSource 인 스턴스 를 설정 하 고 , 카운터 의 increment ( ) 메소드 를 4 번 호출 합니다 . 예 상대 로 , 카운터 의 count 프로 퍼티 는 increment ( ) 가 호출 될 때 마다 3 씩 증가 합니다 . 
 다음 은 Counter 인 스턴스 의 갯 수 를 현재 count 값 으로 부 터 올리 거나 0 방향 으로 내리 는 좀 더 복잡 한 데이터 소스 TowardsZeroSource 입니다 . 
 TowardsZeroSource 클래스 는 CounterDataSource 프로토콜 로 부 터 옵 셔 널 increment ( forCount : ) 메소드 를 구하 고 카운트 를 할 방향 을 결정 하 기 위해 count 인자 값 을 사용 합니다 . count 가 이미 0 인 경우 에 , 메소드 는 더 이상 카 운 팅 하 지 않 는다는 것 을 가리키 기 위해 0 을 반환 합니다 . 
 - 4 에서 0 으로 계산 하 는 기존 Counter 인 스턴스 로 TowardsZeroSource 의 인 스턴스 를 사용 할 수 있 습니다 . 한 번 0 까지 도달 하 면 , 더 이상 계산 하 지 않 습니다 . 
 프로토콜 은 타입 을 준수 하 기 위해 메소드 , 초기 화 , 서브 스크립트 , 계산 프로 퍼티 구현 을 제공 하 여 확장 될 수 있 습니다 . 각 타입 의 개별 적 인 으로 적합 하 게 하 거나 ( conformance ) 이나 전역 함수 에서 처리 하 기 보 다는 , 프로토콜 자체 에서 동작 을 정의 합니다 . 
 예 를 들 어 , RandomNumberGenerator 프로토콜 은 무작위 Bool 값 을 반환 하 도록 random ( ) 메소드 의 결과 를 사용 하 는 , randomBool ( ) 메소드 를 제공 해서 확장 할 수 있 습니다 . 
 프로토콜 에서 확장 을 생성 하 여 , 추가 적 인 수정 없이 준수 하 는 모든 타입 의 메소드 구현 을 자동 으로 가져옵니다 . 
 프로토콜 확장 은 준수 하 는 타입 에 구현 을 추가 할 수 있 지만 , 다른 프로토콜 로부터 프로토콜 을 확장 하 거나 상속 할 수 는 없 습니다 . 프로토콜 상송 은 항상 프로토콜 자체 선언 에서 만 지정 됩니다 . 
 기본 구현 을 제공 하 기 ( Providing Default Implementations ) 
 프로토콜 이 요구 하 는 모든 메소드 나 계산 프로 퍼티 에 기본 구현 을 제공 하 여 프로토콜 확장 을 사용 할 수 있 습니다 . 준수 하 는 타입 이 요구 하 는 메소드 나 프로 퍼티 를 자체 적 인 구현 을 제공 하 는 경우 , 그 구현 은 확장 에 의해 제공 되 는 것 을 대신 해서 사용 될 것 입니다 . 
 확장 으로 기본 구현 이 제공 된 프로토콜 요구사항 ( requirements ) 은 옵 셔 널 프로토콜 요구사항 과 는 다릅니다 . 준수 하 는 타입 이 자체 적 으로 구현 할 필요 는 없 지만 , 기본 구현 이 있 는 요구사항 은 옵 셔 널 체 이닝 없이 호출 될 수 있 습니다 . 
 예 를 들 어 , PrettyTextRepresentable 프로토콜 
 TextRepresentable 프로토콜 을 상속 받 아 단순히 textualDescription 프로 퍼티 에 접근 하 는 결과 를 반환 하 기 위해 , prettyTextualDescription 프로 퍼티 의 기본 구현 을 제공 할 수 있 습니다 . 
 프로토콜 확장 에 제약 조건 추가 하 기 ( Adding Constraints to Protocol Extensions ) 
 프로토콜 확장 을 정의 할 때 , 확장 의 메소드 와 프로 퍼티 가 사용 가능 하 기 전 에 준수 하 는 타입 이 만족 해야 만 하 는 제약 조건 을 지정 할 수 있 습니다 . 이러 한 제약 조건 을 제네릭 where 절 을 작성 해서 확장 하 려는 프로토콜 의 이름 뒤 에 작성 합니다 . 제네릭 where 절 에 대한 자세 한 것 은 제네릭 Where 절 ( Generic Where Clauses ) 을 보 세요 . 
 컬렉션 에 잇 는 모든 요소 들 이 같 을 때 에 만 , allEqual ( ) 메소드 가 true 를 반환 합니다 . 
 하나 는 모든 요소 가 같 고 , 하나 는 그렇 지 않 는 두 개 의 정수 형 배열 을 생각 해 봅니다 . 
 배열 은 Collection 을 준 수 하 고 정수형 은 Equatable 을 준수 하 기 때문 에 , equalNumber 와 differentNumbers 는 allEqual ( ) 메소드 를 사용 할 수 있 습니다 . 
 준수 하 는 타입 이 같 은 메소드 나 프로 퍼티 에 대한 구현 을 제공 하 는 , 여러 개 의 제한 된 확장 에 대한 요구사항 을 만족 하 는 경우 , Swift 는 가장 특별 한 제약 조건 을 위해 해당 구현 을 사용 합니다 . 
 Type Casting ( 0 )