2014-07-03 18 views
9

Ciao Sto usando molto i generici nel mio progetto attuale. Tuttavia, ho riscontrato un problema:Come richiedere un tipo generico implementare un protocollo generico utilizzando un tipo specifico nel protocollo

Ho bisogno di una funzione generica foo<T> per poter prendere un parametro che si conforma a un protocollo generico utilizzando un tipo specifico.

Per esempio in Java che posso fare:

public interface Proto<B> { 
    public void SomeFunction() 
} 
public class SampleClass { 
} 
public class Conforms extends Proto<SampleClass> { 
    @Override 
    public void SomeFunction() {} 
} 
public class TestingClass { 
    public void Requires (Proto<SampleClass> param) { 
     // I can use param 
    } 
} 

Come farei la stessa funzione di Requires() a Swift? So che in Swift usi typealias nel protocollo per generici. Come vincolo un parametro basato sullo typealias?

+0

può essere correlato: http://stackoverflow.com/questions/24231498/swift-require-type-and-protocol-for-method-parameter –

risposta

14

Prototipi non sembrano avere le classi di farmaci generici vie e le strutture fanno a Swift, ma si può avere associato tipi con typealias, che sono vicini.

È possibile utilizzare i vincoli di tipo per assicurarsi che l'oggetto che si passa adotta il Proto con vincoli di tipo. Per fare il Proto si passa in require ha il diritto B, si utilizza where.

Apples documentation on generics ha un sacco di informazioni.

This blog post è anche una buona fonte di informazioni su come fare cose più complicate con i generici.

protocol Proto { 
    typealias B 
    func someFunction() 
} 

class SampleClass {} 

class Conforms : Proto { 
    typealias B = SampleClass 
    func someFunction() { } 
} 

class TestingClass { 
    func requires<T: Proto where T.B == SampleClass>(param: T) { 
     param.someFunction() 
    } 
} 
+0

Si noti che (dal college di hard knocks), a partire dalla Beta 5, Swift non riesce a controllare la clausola where sui tipi associati, portando a errori di runtime quando si chiama require() sopra, con un'istanza di say "AnotherSampleClass" (segnalata ad Apple) –

7

È possibile utilizzare una clausola where per specificare più requisiti per un generico. I pensare il tuo esempio si traduce in questo, ma si blocca Xcode. Beta!

protocol Proto { 
    func someFunction() 
} 
class SampleClass { 
} 
class Conforms: SampleClass, Proto { 
    func someFunction() { 
    } 
} 
class TestingClass { 
    func requires<T: SampleClass >(param: T) where T: Proto { 
     param.someFunction() // it's this line that kills Xcode 
    } 
} 

let testingClass = TestingClass() 
let conforms = Conforms() 
testingClass.requires(conforms) 
+0

Questa dovrebbe essere la risposta accettata –

+0

Lavori in Xcode 7.1. 1, 7.2. – SwiftArchitect

Problemi correlati