🍫 notion으로 보기
*본 포스트는 애플의 'A Swift Tour'를 바탕으로 작성되었으며, 공부하며 기록용으로 작성한 포스트이기 때문에 정확하지 않은 정보가 있을 수 있습니다!
** notion으로 작성한 문서를 임시로 올려둔 포스트이기 때문에 사진 링크의 오류와 문서의 형식 등으로 인해 보시기에 불편함이 있을 수 있습니다. (사진이 안나오거나 코드를 보기 불편한 점 등은 빠른 시일 내에 수정하도록 하겠습니다!)
protocol
프로토콜protocol을 선언하기 위해 protocol
을 사용한다.
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}
***{ get }**
: read only.
***mutating func
:** modify the properties of a value type
클래스, 열거체, 구조체 모두 protocol을 채택할 수 있다.
class SimpleClass: ExampleProtocol {
var simpleDescription: String = "A very simple class."
var anotherProperty: Int = 69105
func adjust() { //modify
simpleDescription += " Now 100% adjusted."
}
}
var a = SimpleClass()
// a.adjust()를 수행
a.adjust()
let aDescription = a.simpleDescription
// "A very simple class. Now 100% adjusted."
struct SimpleStructure: ExampleProtocol {
var simpleDescription: String = "A simple structure"
mutating func adjust() {
simpleDescription += " (adjusted)"
}
}
var b = SimpleStructure()
// b.adjust()를 수행
b.adjust()
let bDescription = b.simpleDescription
// "A simple structure (adjusted)"
❗️SimpleStructure 선언부의 **mutating**
키워드는 구조체를 수정한다는 것을 표시한다. SimpleClass 선언부에서는 그 메소드의 마크가 필요 없는데, 이는 클래스의 메소드는 언제나 클래스를 수정할 수 있기 때문이다.
**experiment**
ExampleProtocol에 다른 필요조건을 추가해라. SimpleClass와 SimpleStructure가 여전히 프로토콜을 따르기 위해서는 어떤 변화를 주어야 하나?
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
func adjustSecond()
}
⛔️ ExampleProtocol을 채택adopt하는 것에 대해 func adjustSecond()를 적어주어야 한다!
extension
재하는 타입에 기능functionality을 추가하기 위해 **익스텐션extension**
을 사용하라. 예를 들어 새로운 메소드나 계산된 속성에 대해서.너는 프로토콜 일치conformance다른곳에서 선언된 타입, 또는 심지어 라이브러리나 프레임워크에서 불러온 타입에도 **프로토콜 준수성protocol conformance**
을 더하기 위해 익스텐션extension
을 사용할 수 있다.
extension Int: ExampleProtocol {
var simpleDescription: String {
return "The number \(self)"
}
mutating func adjust() {
self += 42
}
}
print(7.simpleDescription)
experiment
absoluteValue 속성을 추가한 Double 타입 익스텐션을 작성하라.
?????????
extension Double: ExampleProtocol {
var simpleDescription: String {
return "The number \(self)"
}
mutating func adjust() {
if self < 0{
self = abs(self)
}
}
}
var number = -7.34
프로토콜 이름을 다른 이름 있는 타입named type으로 해도 된다. 예를 들어, 다른 타입들을 가졌지만 모두 단일 프로토콜을 따르는 객체의 콜렉션을 생성하기 위해서 그럴 수 있다. 값의 타입이 프로토콜 타입인 값들과 작업을 할 때, 프로토콜의 정의 밖에 있는 메소도드들은 사용할 수 없다.
let protocolValue: ExampleProtocol = a
print(protocolValue.simpleDescription)
// Prints "A very simple class. Now 100% adjusted."
// print(protocolValue.anotherProperty) // Uncomment to see the error
protocolValue가 SimpleClass의 런타임 타입을 가졌다고 하더라도, 컴파일러는 ExampleProtocol의 타입을 받은 것으로 취급한다. 이는 프로토콜 준수protocol comformance와 별개로 클래스가 실행한implements 메소드나 속성에 우연적으로 접근할 수 없음을 의미한다.