🔥 프로토콜 타입의 컬렉션

476자
6분

프로토콜은 다양한 타입에서 공통적인 기능을 정의하는 강력한 도구랍니다. 프로토콜을 활용하면 코드의 재사용성과 유연성을 높일 수 있어요. 이번 장에서는 프로토콜을 컬렉션의 요소 타입으로 사용하는 방법에 대해 알아볼 거예요.

프로토콜을 타입으로 사용하기

프로토콜은 타입으로 사용될 수 있어요. 이는 변수, 상수, 함수의 매개변수, 반환 값 등의 타입으로 프로토콜을 지정할 수 있다는 것을 의미하죠. 프로토콜을 타입으로 사용하면 해당 프로토콜을 준수하는 모든 타입의 인스턴스를 할당할 수 있습니다.

다음은 TextRepresentable 프로토콜을 타입으로 사용하는 예시예요.

let things: [TextRepresentable] = [game, d12, simonTheHamster]
swift

위 코드에서 thingsTextRepresentable 프로토콜을 요소 타입으로 갖는 배열이에요. 배열에는 TextRepresentable 프로토콜을 준수하는 game, d12, simonTheHamster 인스턴스가 할당되었어요.

프로토콜 타입 컬렉션 다루기

프로토콜 타입의 컬렉션은 일반적인 컬렉션과 동일한 방식으로 다룰 수 있어요. 예를 들어, 프로토콜 타입의 배열을 순회하면서 각 요소에 접근할 수 있죠.

for thing in things {
    print(thing.textualDescription)
}
swift

위 코드에서 things 배열을 순회하면서 각 요소의 textualDescription 속성에 접근하여 출력하고 있네요. TextRepresentable 프로토콜은 textualDescription 속성을 요구하므로, 배열의 모든 요소는 해당 속성을 가지고 있다는 것이 보장됩니다.

출력 결과는 다음과 같아요.

A game of Snakes and Ladders with 25 squares
A 12-sided dice
A hamster named Simon
text

각 요소의 실제 타입은 Dice, DiceGame, Hamster 등 다양할 수 있지만, things 배열의 요소 타입은 TextRepresentable이에요. 따라서 thing 상수는 TextRepresentable 타입으로 추론되며, textualDescription 속성에 안전하게 접근할 수 있답니다.

프로토콜 타입 컬렉션의 활용

프로토콜 타입의 컬렉션은 다양한 상황에서 활용될 수 있어요. 몇 가지 예시를 살펴볼게요.

이종 컬렉션 (Heterogeneous Collections)

서로 다른 타입의 객체를 하나의 컬렉션에 저장해야 할 때 프로토콜 타입을 사용할 수 있어요. 예를 들어, 도형 객체들을 저장하는 배열을 생성할 때, Shape 프로토콜을 요소 타입으로 사용할 수 있죠.

protocol Shape {
	func draw()
}
 
struct Circle: Shape {
	 func draw() {
			 // 원 그리기 구현
	 }
}
 
struct Rectangle: Shape {
	 func draw() {
			 // 사각형 그리기 구현
	 }
}
 
let shapes: [Shape] = [Circle(), Rectangle(), Circle()]
swift

위 코드에서 shapes 배열은 Shape 프로토콜을 요소 타입으로 가지며, CircleRectangle 인스턴스를 저장하고 있네요.

프로토콜 확장 메서드 활용

프로토콜 타입의 컬렉션에 대해 프로토콜 확장 메서드를 활용할 수 있답니다. 프로토콜 확장을 통해 공통적인 기능을 추가할 수 있어 코드의 재사용성을 높일 수 있어요.

extension Sequence where Element: TextRepresentable {
	func printTextualDescription() {
		 for element in self {
				 print(element.textualDescription)
		 }
	}
}
 
things.printTextualDescription()
swift

위 코드에서 Sequence 프로토콜을 확장하여 ElementTextRepresentable인 경우에 printTextualDescription() 메서드를 추가했어요. 이제 TextRepresentable 프로토콜을 준수하는 요소를 가진 모든 컬렉션에서 printTextualDescription() 메서드를 호출할 수 있게 되었죠.

정리해 보면, 프로토콜은 컬렉션의 요소 타입으로 사용될 수 있어요. 프로토콜 타입의 컬렉션을 사용하면 다양한 타입의 객체를 하나의 컬렉션에 저장하고 다룰 수 있답니다. 또한 프로토콜 확장을 통해 공통적인 기능을 추가할 수 있어 코드의 재사용성과 유연성을 높일 수 있죠.

프로토콜 타입의 컬렉션은 이종 컬렉션을 다루는 데 유용하며, 프로토콜에 정의된 공통 인터페이스를 통해 컬렉션의 요소에 접근할 수 있어요. 이를 통해 코드의 가독성과 유지보수성을 향상시킬 수 있답니다.

프로토콜과 컬렉션을 함께 활용하면 더욱 강력하고 유연한 코드를 작성할 수 있어요. 다양한 상황에서 프로토콜 타입의 컬렉션을 적절히 활용하여 코드의 구조를 개선해 보는 건 어떨까요?