일반 메서드에서 프로토콜 기본 구현 호출
그런 일을 할 수 있는지 궁금합니다.
다음과 같은 놀이터가 있습니다.
protocol Foo {
func testPrint()
}
extension Foo {
func testPrint() {
print("Protocol extension call")
}
}
struct Bar: Foo {
func testPrint() {
// Calling self or super go call default implementation
self.testPrint()
print("Call from struct")
}
}
let sth = Bar()
sth.testPrint()
기본 구현을에서 제공 할 수 extension
있지만 기본 구현에있는 Bar
모든 항목과 추가 항목이 필요한 경우 어떻게 해야 우리합니까? 모든 속성 등을 구현하는 요구 사항을 위해 es에서 메서드
를 호출 super.
하는 것과 비슷 class
하지만 structs
.
여전히 이것에 대한 답을 찾고 있는지는 모르겠지만, 그 프로토콜을 정의에서 함수를 제거하는 방법을 캐스트 Foo
한 다음 메서드를 호출하는 것입니다.
protocol Foo {
// func testPrint() <- comment this out or remove it
}
extension Foo {
func testPrint() {
print("Protocol extension call")
}
}
struct Bar: Foo {
func testPrint() {
print("Call from struct")
(self as Foo).testPrint() // <- cast to Foo and you'll get the default
// function defined in the extension
}
}
Bar().testPrint()
// Output: "Call from struct"
// "Protocol extension call"
어떤 MMS 함수가 프로토콜의 일부로 선언되지 않고 프로토콜에 대한 확장으로 정의 된 경우에만 작동합니다. 그림을 이동합니다. 하지만 작동합니다.
글쎄, 당신은 프로토콜을 준수하는 중첩 된 유형을 만들고, 인스턴스화하고, 그 유형에 대한 메소드를 호출 할 수 있습니다 (프로토콜 확장 내부의 구현이 어쨌든 그것을 참조 할 수 없기 때문에 유형의 데이터에 액세스 할 수 있습니다. 중요하지 않습니다). 그러나 그것은 내가 우아 부르는 해결책이 아닙니다.
struct Bar: Foo {
func testPrint() {
// Calling default implementation
struct Dummy : Foo {}
let dummy = Dummy()
dummy.testPrint()
print("Call from struct")
}
}
감사합니다! 프로토콜에 함수를 정의를 생성하면 객체가 프로토콜로 캐스팅 될 때 내부에서 호출하는 Apple의 새 주소를 얻습니다.
다음과 같은 버전을 시도했습니다.
import UIKit
protocol MyProc
{
}
protocol MyFuncProc
{
func myFunc()
}
extension MyProc
{
func myFunc()
{
print("Extension Version")
}
}
struct MyStruct: MyProc, MyFuncProc
{
func myFunc()
{
print("Structure Version")
(self as MyProc).myFunc()
}
}
(MyStruct() as MyFuncProc).myFunc()
이것은 다음과 같은 출력을 제공합니다.
Structure Version
Extension Version
프로토콜에 associatedType
또는 Self
요구 사항 이있는 경우 캐스트가 작동하지 않습니다. 이 문제를 해결하려면 일반 기본 구현과 준수 유형이 모두 호출 할 수있는 "그림자"기본 구현을 만듭니다.
protocol Foo {
associatedType Bar
}
extension Foo {
func testPrint() {
defaultTestPrint()
}
}
fileprivate extension Foo { // keep this as private as possible
func defaultTestPrint() {
// default implementation
}
}
struct Bar: Foo {
func testPrint() {
// specialized implementation
defaultTestPrint()
}
}
이러한 문제를 해결하는 방법에 대해 어떻게 생각하십니까?
protocol Foo {
func testPrint()
}
extension Foo {
func testPrint() {
defaultTestPrint()
}
func defaultTestPrint() {
print("Protocol extension call")
}
}
struct Bar: Foo {
func testPrint() {
// Calling self or super go call default implementation
defaultTestPrint()
print("Call from struct")
}
}
let sth = Bar()
sth.testPrint()
'ProgramingTip' 카테고리의 다른 글
Android 웹 페이지에서 입력 확대 / 축소 (0) | 2020.10.27 |
---|---|
TeamCity로 빌드 한 후 배포하는 방법은 무엇입니까? (0) | 2020.10.27 |
Dispatcher.BeginInvoke : 람다를 System.Delegate로 변환 할 수 없습니다. (0) | 2020.10.26 |
T-SQL에 노드를 연결하는 존재 함수가 있습니까? (0) | 2020.10.26 |
"JPEG 파일이 아닙니다 : 0x89 0x50으로 시작"오류가 발생하는 이유 (0) | 2020.10.26 |