How do I specify that a non-generic Swift type should comply to a protocol?

后端 未结 3 1743
庸人自扰
庸人自扰 2020-12-08 06:34

I\'d like to implement a Swift method that takes in a certain class type, but only takes instances of those classes that comply to a specific protocol. For example, in Objec

相关标签:
3条回答
  • 2020-12-08 06:59

    this method header from ObjC:

    - (void)addFilter:(GPUImageOutput<GPUImageInput> *)newFilter { ... }
    

    is identical to this header in Swift:

    func addFilter<T: GPUImageOutput where T: GPUImageInput>(newFilter: T?) { ... }
    

    both method will accept the same set of classes

    • which is based on GPUImageOutput class; and
    • conforms GPUImageInput protocol; and
    • the newFilter is optional, it can be nil;
    0 讨论(0)
  • 2020-12-08 07:18

    Is swift you must use generics, in this way:

    Given these example declarations of protocol, main class and subclass:

    protocol ExampleProtocol {
        func printTest()   // classes that implements this protocol must have this method
    }
    
    // an empty test class
    class ATestClass
    {
    
    }
    
    // a child class that implements the protocol
    class ATestClassChild : ATestClass, ExampleProtocol
    {
        func printTest()
        {
            println("hello")
        }
    }
    

    Now, you want to define a method that takes an input parameters of type ATestClass (or a child) that conforms to the protocol ExampleProtocol. Write the method declaration like this:

    func addFilter<T where T: ATestClass, T: ExampleProtocol>(newFilter: T)
    {
        println(newFilter)
    }
    

    Your method, redefined in swift, should be

    func addFilter<T where T:GPUImageOutput, T:GPUImageInput>(newFilter:T!)
    {
        // ...
    }
    

    EDIT:

    as your last comment, an example with generics on an Enum

        enum OptionalValue<T> {
            case None
            case Some(T)
        }
        var possibleInteger: OptionalValue<Int> = .None
        possibleInteger = .Some(100)
    

    Specialized with protocol conformance:

        enum OptionalValue<T where T:GPUImageOutput, T:GPUImageInput> {
            case None
            case Some(T)
        }
    

    EDIT^2:

    you can use generics even with instance variables:

    Let's say you have a class and an instance variable, you want that this instance variable takes only values of the type ATestClass and that conforms to ExampleProtocol

    class GiveMeAGeneric<T: ATestClass where T: ExampleProtocol>
    {
        var aGenericVar : T?
    }
    

    Then instantiate it in this way:

        var child = ATestClassChild()
        let aGen = GiveMeAGeneric<ATestClassChild>()
        aGen.aGenericVar = child
    

    If child doesn't conform to the protocol ExampleProtocol, it won't compile

    0 讨论(0)
  • 2020-12-08 07:23

    From Swift 4 onwards you can do:

    func addFilter(newFilter: GPUImageOutput & GPUImageInput)
    

    Further reading: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html

    http://braking.github.io/require-conformance-to-multiple-protocols/

    Multiple Type Constraints in Swift

    0 讨论(0)
提交回复
热议问题