2015-09-16 10 views
47

Böyle bir şeye ulaşmanın mümkün olup olmadığını merak ediyorum.Normal protokolden varsayılan protokol uygulaması çağrılıyor

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() 

Ben extension varsayılan bir uygulama sağlayabilir ama ne olursa Bar varsayılan uygulanması artı ek şeylerde her şeyi gerekir:
Böyle bir Playground var?
super. yönteminin, class numaralı telefonlarda aranan her özelliği yerine getirme gereksinimini yerine getirmesine benzer. Ancak, structs ile aynı sonucu elde etme olasılığını göremiyorum.

+0

- sorun nedeniyle segmentasyon başarısız olmasıdır hata (7.0 GM ve 7.1 beta sürümünde test edilmiştir) – Antonio

+0

Bu garip bir yapıdır sunduğunuz tion – cojoj

+2

Her örnek yöntemi, ilk parametresi olan – Antonio

cevap

54

hala bu bir cevap arıyorsanız bilmiyorum, ama bunu yapmanın yolu protokol tanımından işlevini kaldırmaktır, Foo için nesne döküm ve ardından yöntemini çağırın o: fonksiyon protokolünün bir parçası olarak bildirilmedi, ancak protokole bir uzantısı tanımlanması durumunda sadece çalışır nedense

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" 

. Git rakamı. Ama işe yarıyor.

+0

Yararlı olabileceğinden, bu özellik için bir özellik radarı kaydedeceğim. Evet, bu çözüm yolunda harika olan bazı bloglarda bu çözümü buldum ... – cojoj

+0

Oh tanr! Protokolden çikarmanizi zorladilarina inanamiyorum! iyi cevap, teşekkür ederim! –

+2

Bu benim için bir hata gibi görünüyor, bu sadece aynı örneği döküm ederek farklı yöntem uygulaması elde etmek mümkün olmamalı. –

5

Protokolüne uyan iç içe bir tür oluşturabilir, bunu başlatabilir ve bu yöntemde yöntemini çağırabilirsiniz (iletişim kuralı uzantısı içindeki uygulama, türünün verilerine erişemediğiniz için önemli değildir;). Ama zarif dediğim bir çözüm değil.

struct Bar: Foo { 
    func testPrint() { 
     // Calling default implementation 
     struct Dummy : Foo {} 
     let dummy = Dummy() 
     dummy.testPrint() 
     print("Call from struct") 
    } 
} 
+1

Şu anda tek bir olasılık gibi görünüyor (Apple tarafından onaylanmış) – cojoj

1

Gönderi için teşekkürler! Protokolde işlev tanımını koyarsanız, nesne protokole dökülürse, yalnızca nesnenin işlevinin sürümünü görür ve kendi içinde arama yaptığınız için, Apple'ın yeni adresini alırsınız ...

I Bu bir çıkış verir

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() 

: böyle bir sürümünü çalıştım ben `Foo.testPrint (öz)()` kullanacağı

Structure Version 
Extension Version