2014-07-12 7 views
25

Ben Swift aşağıdaki yapmaya çalışılıyor Protocol 'ProtocolWithAlias' can only be used as a generic constraint because it has Self or associated type requirements.Bu protokol neden "sadece genel bir kısıtlama olarak kullanılabilir"?</p> <pre><code>protocol ProtocolWithAlias { typealias T } protocol AnotherProtocol { func someFunc() -> ProtocolWithAlias } </code></pre> <p>Ama hatayı alıyorum:

Böyle bir şey yapmak mümkün mü? Hata mesajı (veya en azından "only be used as a generic constraint" bölümü) bana pek bir şey ifade etmiyor.

Ben son Xcode 6 beta 3.

Teşekkür kullanıyorum!

cevap

23

bu deneyin: Biz her türlü ProtocolWithAlias ​​ uygulayan kabul edip birlikte bir şeyler yapabiliriz bir tüketici geçmesi someFunc yerine arasında bir değer dönen:

func someFunc<T:ProtocolWithAlias>() -> T 
+0

Eğer böyle bitti neden bilmek ne olacağını ben someFunc gerçeklenimine sahip taklit Sağlar? Oldukça garip bir sözdizimine benziyor, ama belki de bu sadece C# için kullanıldığımdan kaynaklanıyor :) – MatthewSot

+7

Sorun şu ki, tip sistemi protokolü belirttiğinizde, ilişkili sistem için neyin takılacağını bilmiyor, bunun yerine protokole uygun herhangi bir beton türünü döndürmek için uzmanlaşmış olabilecek genel bir işlev yaparsınız, ancak sadece "protokol" değil. Derleyici, muhtemelen bunu çözebilmelidir, ancak şu anda olamaz. –

+2

güzel ama bu genel protokolü bir sınıfın örnek değişkenine nasıl belirtilir? – Dragouf

10

O kontrolünü ters çevirerek bu uygulamak mümkün o.

protocol ProtocolWithAlias { 
    typealias T 
} 

protocol ProtocolConsumer { 
    func consume<T: ProtocolWithAlias>(value: T) 
} 

protocol AnotherProtocol { 
    func someFunc(consumer: ProtocolConsumer) 
} 

Bu numara continuation passing style (CPS) fonksiyonu transforme olarak bilinir. Ne yazık ki bunu CPSing olmadan uygulamak için herhangi bir yol bulamadık. Baktığımız tip sistem özelliği varoluşsal tipler (ve this iş parçacığının iyi bir açıklaması var), fakat Swift'in onları desteklemediğini düşünüyorum (henüz).


Diğer yanıt neden doğru değil?

func someFunc<T:ProtocolWithAlias>() -> T 

bu fonksiyon ProtocolWithAlias ​​arayan seçer uygulayan herhangi bir türü için T türünde bir değer döndürebilir yani ama biz tarafından seçilecek istedi: Bu imza söyler neler numaralı telefondan.

Bu işlevin mantıklı bir uygulamasını yazmak bile mümkün değil. Ben ProtocolWithAlias ​​ uygulayan yeni bir sınıf oluşturmak ve someFunc nasılsa bu sınıfın örneğini oluşturmak için isteği:

class Uninhabited: ProtocolWithAlias { 
    typealias T = Int 
    init(nope: Uninhabited) {} 
} 

... 

let impossible: Uninhabited = someFunc<Uninhabited>()