
프로토콜은 어떤 구조가 따라야 하는 형식이나 규칙을 말한다. 일종의 템플릿 같은 개념.
다음은 프로토콜 선언 예시이다.
protocol MessageBuilder {
var name: String { get }
func buildMessage() -> String
}
위 프로토콜을 채택하면 1. name이라는 문자열 프로퍼티와 2. 매개변수를 받지 않고 문자열을 반환하는 buildMessage() 메서드를 반드시 포함해야 한다.
class MyClass: MessageBuilder{
var name: String
init(name:String) {
self.name = name
}
func BuildMessage() -> String {
"Hello" + name
}
}
이런식으로 사용됨.
SwiftUI 쓸 때, var body: some View 에서 some이 어떤 역할인지 너무 궁금했음.
책으로 보고 이해가 잘 안돼서 구글링해서 겨우겨우 이해했다... 프로토콜과 함께 있어야 하는 친구임.
이 때 프로토콜명 앞에 some을 붙여주면, 전체 식 내부에서 프로토콜을 잘 따르기만 한다면 컴파일러는 그 전체식을 하나로 싸잡아서 '불투명 반환 타입(opaque type)'으로 처리하고, 프로토콜명만 반환함. 이에 따라 구체적, 세부적 타입 구조는 숨겨지고 감춰짐.
some 을 사용하면...
1. 모든 프로토콜을 일일히 개별적으로 구성하지 않아도 된다.
2. 타입 정보를 감춰 모듈과 모듈의 결합성을 낮춘다.
3. 공개 API 내에서 사용되는 반환 타입을 의도적으로 숨길 수 있다.
이렇게 some을 사용하여 모든 클래스 등을 불투명 반환 타입으로 바꾸면 올바르지 않은 추정으로 문제가 발생하지 않을까 우려될 수 있다. 우리는 반환 타입만 보면 내부 정보를 알 수 없지만, Swift 컴파일러는 내부의 숨겨진 정보에 접근할 수 있다. 따라서 그런 우려는 안 해도 됨.
func doubleFunc(value: Int) -> some Equatable{
value *2
}
func doubleFunc2(value: String) -> some Equatable{
value + value
}
let intOne = doubleFunc1(value: 10)
let stringOne = doubleFunc2(value: "Ten")
if(intOne == StringOne) {
print("They match")
}
위 예제를 적용하면, intOne과 stringOn은 둘 다 'some Equatable'을 반환하여 '=='연산자를 적용시킬 수 없다는 오류 메세지를 준다.
📚 참고도서
[SwiftUI 기반의 iOS 프로그래밍]