How to execute different implementation of a method of a generic struct based on the generic type?

后端 未结 1 986
攒了一身酷
攒了一身酷 2021-01-29 06:59

I have a generic struct. I have added a method to the struct in an extension as follows-

struct CustomStruct {         


        
相关标签:
1条回答
  • 2021-01-29 07:43

    The issue can't be reproduced from the example you gave. I'm going to assume that you are having a more complicated issue, that you tried to boil it down for this question, and that you boiled it down incorrectly. I'm going to guess that what you're actually seeing is something like this:

    struct CustomStruct<T> {
        let data: T?
        func method1() {
            print("original method1")
        }
        func method2() {
            method1()
        }
    }
    extension CustomStruct where T == String {
        func method1() {
            print("method1 for string called")
        }
    }
    let struct1 = CustomStruct(data: "something")
    struct1.method1() // method1 for string called
    struct1.method2() // original method1
    

    As you can see, if we call method1 directly, ourselves, we pass through the extension. (That's why the issue can't be reproduced from the example you gave.) But if we call method2, which calls method1, we get the original method1, not the one belonging to the extension.

    Is that the real issue?

    If so, you may be experiencing a common misconception, in which you are attempting to use a where clause to enable some sort of type-based dispatch. That's wrong, and is not what a where clause is for. As Jordan Rose puts it here:

    In Swift, the function that gets called is chosen at the place where the call is made.

    The way to get type-based dispatch (as he goes on to say) is through standard approaches like overriding (polymorphism) and overloading (distinct method signatures). Or you can of course examine the type yourself and make a decision in real time.

    To put it another way: you can't use an extension to perform a method override. But that's exactly what you're attempting to do. You can't use where clauses to turn a struct into a class (dynamic dispatch), or to do the job of overloading.

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