swiftgenericsswift4extension-methodsswift4.1

How to create extension for a generic structure that will be available only for Optional generic parameters in Swift 4.1?


I have the following structure in my iOS application:

struct MyStruct<T> {

    var property1: T
    var property2: T

    init(property1: T, property2: T) {
        self.property1 = property1
        self.property2 = property2
    }

    init(allPropertiesWith value: T) {
        self.property1 = value
        self.property2 = value
    }
}

I also have 2 classes that don't have a common ancestor:

class A { }
class B { }

In my application I have instances of MyStruct<A>, MyStruct<B>, MyStruct<A?>, MyStruct<B?> and I use them in these functions:

func f1(myStrurct: MyStruct<A?>) { }

func f2(myStrurct: MyStruct<A>) { }

func g2() {
    f1(myStrurct: MyStruct<A?>(property2: A()))
} 
/* I also have the same functions for MyStruct<B> and MyStruct<B?> */

I cannot modify f1, f2 and g2. That's why I created 2 extensions to make initialisation of MyStruct<T> easier:

extension MyStruct where T == A? {

    init(property1: T) {
        self.property1 = property1
        self.property2 = nil
    }

    init(property2: T) {
        self.property1 = nil
        self.property2 = property2
    }
}

extension MyStruct where T == B? {

    init(property1: T) {
        self.property1 = property1
        self.property2 = nil
    }

    init(property2: T) {
        self.property1 = nil
        self.property2 = property2
    }
}

As you can see these extensions are almost the same. Is it possible to refactor it with only 1 extension?


Solution

  • In the answer provided by Rakesha Shastri I found out that I can use protocol to refactor my code. However to be able to use this solution I need to rewrite other parts of my application. I tried to add the solution by Rakesha Shastri to my application and compile it with Swift 3, Swift 4 or Swift 4.2 (all Swift versions available in Xcode 10.0), but every time I received a compiler error. It means that currently there are no ways how to solve the problem that I described in this question.