Associatedtype usage inside Protocols and Generic functions












2















Let's assume I've a protocol Foo with an associatedtype Bar. Is there any way to use this same associatedtype as a constraint in a generic function inside this same protocol?



To illustrate:



protocol Foo {
associatedtype Bar
func example<T: Bar>() -> T
}


This will throw a Inheritance from non-protocol, non-class type 'Self.Bar'. Which makes total sense, because at compile-time, we don't know which type Bar will be.



Nonetheless, for some reason, even if I define the Bar type, I will still get the same error. Something like this:



protocol Foo {
associatedtype Bar: NSObject //OR: Protocol
func example<T: Bar>() -> T //Compile Error: Inheritance from non-protocol, non-class type 'Self.Bar'
}


Both this and this questions address the same issue, but none of them are real answers in my honest opinion.



Also, maybe I'm approaching this in a wrong perspective of the language, but to visualize my use case: I need that when the class defines the type of Bar, each T used in example() function, should be a Bar type, but knowing which type it will return.
To illustrate what would be my state of art:



protocol Foo {
associatedtype Bar: NSObject //OR: Protocol
//Compile Error: Inheritance from non-protocol, non-class type 'Self.Bar'
func example<T: Bar>() -> T //OR: func example<T>() -> T where T: Bar
}

class ExampleBarType: NSObject { }

class ExampleObject: ExampleBarType { }

class FooImplementation: Foo {
typealias Bar = ExampleBarType

func example<T: Bar>() -> T { //OR: func example<T>() -> T where T: Bar {

}
}


I just can't seem to grasp why the compiler can't assume that my associatedtype will be the one that I've defined. Thanks in advance.










share|improve this question



























    2















    Let's assume I've a protocol Foo with an associatedtype Bar. Is there any way to use this same associatedtype as a constraint in a generic function inside this same protocol?



    To illustrate:



    protocol Foo {
    associatedtype Bar
    func example<T: Bar>() -> T
    }


    This will throw a Inheritance from non-protocol, non-class type 'Self.Bar'. Which makes total sense, because at compile-time, we don't know which type Bar will be.



    Nonetheless, for some reason, even if I define the Bar type, I will still get the same error. Something like this:



    protocol Foo {
    associatedtype Bar: NSObject //OR: Protocol
    func example<T: Bar>() -> T //Compile Error: Inheritance from non-protocol, non-class type 'Self.Bar'
    }


    Both this and this questions address the same issue, but none of them are real answers in my honest opinion.



    Also, maybe I'm approaching this in a wrong perspective of the language, but to visualize my use case: I need that when the class defines the type of Bar, each T used in example() function, should be a Bar type, but knowing which type it will return.
    To illustrate what would be my state of art:



    protocol Foo {
    associatedtype Bar: NSObject //OR: Protocol
    //Compile Error: Inheritance from non-protocol, non-class type 'Self.Bar'
    func example<T: Bar>() -> T //OR: func example<T>() -> T where T: Bar
    }

    class ExampleBarType: NSObject { }

    class ExampleObject: ExampleBarType { }

    class FooImplementation: Foo {
    typealias Bar = ExampleBarType

    func example<T: Bar>() -> T { //OR: func example<T>() -> T where T: Bar {

    }
    }


    I just can't seem to grasp why the compiler can't assume that my associatedtype will be the one that I've defined. Thanks in advance.










    share|improve this question

























      2












      2








      2


      1






      Let's assume I've a protocol Foo with an associatedtype Bar. Is there any way to use this same associatedtype as a constraint in a generic function inside this same protocol?



      To illustrate:



      protocol Foo {
      associatedtype Bar
      func example<T: Bar>() -> T
      }


      This will throw a Inheritance from non-protocol, non-class type 'Self.Bar'. Which makes total sense, because at compile-time, we don't know which type Bar will be.



      Nonetheless, for some reason, even if I define the Bar type, I will still get the same error. Something like this:



      protocol Foo {
      associatedtype Bar: NSObject //OR: Protocol
      func example<T: Bar>() -> T //Compile Error: Inheritance from non-protocol, non-class type 'Self.Bar'
      }


      Both this and this questions address the same issue, but none of them are real answers in my honest opinion.



      Also, maybe I'm approaching this in a wrong perspective of the language, but to visualize my use case: I need that when the class defines the type of Bar, each T used in example() function, should be a Bar type, but knowing which type it will return.
      To illustrate what would be my state of art:



      protocol Foo {
      associatedtype Bar: NSObject //OR: Protocol
      //Compile Error: Inheritance from non-protocol, non-class type 'Self.Bar'
      func example<T: Bar>() -> T //OR: func example<T>() -> T where T: Bar
      }

      class ExampleBarType: NSObject { }

      class ExampleObject: ExampleBarType { }

      class FooImplementation: Foo {
      typealias Bar = ExampleBarType

      func example<T: Bar>() -> T { //OR: func example<T>() -> T where T: Bar {

      }
      }


      I just can't seem to grasp why the compiler can't assume that my associatedtype will be the one that I've defined. Thanks in advance.










      share|improve this question














      Let's assume I've a protocol Foo with an associatedtype Bar. Is there any way to use this same associatedtype as a constraint in a generic function inside this same protocol?



      To illustrate:



      protocol Foo {
      associatedtype Bar
      func example<T: Bar>() -> T
      }


      This will throw a Inheritance from non-protocol, non-class type 'Self.Bar'. Which makes total sense, because at compile-time, we don't know which type Bar will be.



      Nonetheless, for some reason, even if I define the Bar type, I will still get the same error. Something like this:



      protocol Foo {
      associatedtype Bar: NSObject //OR: Protocol
      func example<T: Bar>() -> T //Compile Error: Inheritance from non-protocol, non-class type 'Self.Bar'
      }


      Both this and this questions address the same issue, but none of them are real answers in my honest opinion.



      Also, maybe I'm approaching this in a wrong perspective of the language, but to visualize my use case: I need that when the class defines the type of Bar, each T used in example() function, should be a Bar type, but knowing which type it will return.
      To illustrate what would be my state of art:



      protocol Foo {
      associatedtype Bar: NSObject //OR: Protocol
      //Compile Error: Inheritance from non-protocol, non-class type 'Self.Bar'
      func example<T: Bar>() -> T //OR: func example<T>() -> T where T: Bar
      }

      class ExampleBarType: NSObject { }

      class ExampleObject: ExampleBarType { }

      class FooImplementation: Foo {
      typealias Bar = ExampleBarType

      func example<T: Bar>() -> T { //OR: func example<T>() -> T where T: Bar {

      }
      }


      I just can't seem to grasp why the compiler can't assume that my associatedtype will be the one that I've defined. Thanks in advance.







      swift generics protocols swift-protocols






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 22 '18 at 17:28









      Guilherme MatuellaGuilherme Matuella

      399113




      399113
























          3 Answers
          3






          active

          oldest

          votes


















          0














          I know it's an advanced topic. May this way can give you some lights.



          protocol Foo {
          associatedtype Bar: NSObject //OR: Protocol
          func example() -> Bar //OR:
          }

          class ExampleBarType: NSObject { }

          class ExampleObject: ExampleBarType { }

          class FooImplementation: Foo {
          typealias Bar = ExampleBarType
          func example<T: Bar>() -> T {
          return Bar.init() as! T
          }
          }





          share|improve this answer
























          • Yeah, this is currently the workaround I'm using, and it's exactly what I didn't wanted to do - to cast the return of my Type T -, but thanks for the tip.

            – Guilherme Matuella
            Nov 22 '18 at 18:21













          • What happens if I call let x: BarSubclass = foo.example()? I would expect that to crash. A Bar can't be as-cast to BarSubclass.

            – Rob Napier
            Nov 22 '18 at 22:55



















          0














          I'm not sure I'm fully understanding your use case but, isn't this enough for doing what you need to do?



          protocol Foo {
          associatedtype Bar
          func example() -> Bar
          }

          protocol BarProtocol { }

          class BarOne: BarProtocol { }

          class BarTwo: BarProtocol { }

          class FooImplementationOne: Foo {
          func example() -> BarProtocol {
          return BarOne()
          }
          }

          class FooImplementationTwo: Foo {
          func example() -> BarProtocol {
          return BarTwo()
          }
          }





          share|improve this answer
























          • Hey, thanks for answering. But no, this doesn't solve, mainly because I would always need to cast the return of example. Using your example for instance, the function FooImplementationOne example() function should return a BarOne instance, and FooImplementationTwo example() function should explicitly return a BarTwo instance. When you remove the generics from the example() function, it just knows that the type is BarProtocol meaning that I would've to cast everytime I wanted its type.

            – Guilherme Matuella
            Nov 22 '18 at 18:18





















          0














          What you're designing here isn't possible to implement. This isn't a Swift problem; I mean it's literally not possible to implement because the types don't make the promises you need. Consider this part:



          class ExampleBarType {} // Not an NSObject subclass.

          class FooImplementation: Foo {
          typealias Bar = ExampleBarType

          func example<T: Bar>() -> T {
          // What would you write here?
          }
          }


          How do you plan to write that function body? Consider the following caller:



          class MyBar: Bar {        
          init(x: Int) {}
          }

          let ex: MyBar = foo.example()


          How would you implement example? How can you construct MyBar? You don't know the parameters for the init method (it requires an Int that you don't have). But your function signature claims that this function will return whatever specific subclass of Bar the caller requests.



          In general you should avoid mixing protocols, generics, and subclassing in the same type system. They pull in different directions and it is very difficult to keep your system coherent. You're going to wind up with a lot of cases where you can't fulfill your promises.



          You should go back to your concrete problem and need. If you're doing this "because I want to be as generic as possible," I recommend stopping. The Swift type system is very powerful, but also has some very tricky limitations, and "as generic as possible just because" almost always slams into those restrictions. If you have a concrete use case in a real program, however, you often (though not always) can avoid those headaches.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435863%2fassociatedtype-usage-inside-protocols-and-generic-functions%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            I know it's an advanced topic. May this way can give you some lights.



            protocol Foo {
            associatedtype Bar: NSObject //OR: Protocol
            func example() -> Bar //OR:
            }

            class ExampleBarType: NSObject { }

            class ExampleObject: ExampleBarType { }

            class FooImplementation: Foo {
            typealias Bar = ExampleBarType
            func example<T: Bar>() -> T {
            return Bar.init() as! T
            }
            }





            share|improve this answer
























            • Yeah, this is currently the workaround I'm using, and it's exactly what I didn't wanted to do - to cast the return of my Type T -, but thanks for the tip.

              – Guilherme Matuella
              Nov 22 '18 at 18:21













            • What happens if I call let x: BarSubclass = foo.example()? I would expect that to crash. A Bar can't be as-cast to BarSubclass.

              – Rob Napier
              Nov 22 '18 at 22:55
















            0














            I know it's an advanced topic. May this way can give you some lights.



            protocol Foo {
            associatedtype Bar: NSObject //OR: Protocol
            func example() -> Bar //OR:
            }

            class ExampleBarType: NSObject { }

            class ExampleObject: ExampleBarType { }

            class FooImplementation: Foo {
            typealias Bar = ExampleBarType
            func example<T: Bar>() -> T {
            return Bar.init() as! T
            }
            }





            share|improve this answer
























            • Yeah, this is currently the workaround I'm using, and it's exactly what I didn't wanted to do - to cast the return of my Type T -, but thanks for the tip.

              – Guilherme Matuella
              Nov 22 '18 at 18:21













            • What happens if I call let x: BarSubclass = foo.example()? I would expect that to crash. A Bar can't be as-cast to BarSubclass.

              – Rob Napier
              Nov 22 '18 at 22:55














            0












            0








            0







            I know it's an advanced topic. May this way can give you some lights.



            protocol Foo {
            associatedtype Bar: NSObject //OR: Protocol
            func example() -> Bar //OR:
            }

            class ExampleBarType: NSObject { }

            class ExampleObject: ExampleBarType { }

            class FooImplementation: Foo {
            typealias Bar = ExampleBarType
            func example<T: Bar>() -> T {
            return Bar.init() as! T
            }
            }





            share|improve this answer













            I know it's an advanced topic. May this way can give you some lights.



            protocol Foo {
            associatedtype Bar: NSObject //OR: Protocol
            func example() -> Bar //OR:
            }

            class ExampleBarType: NSObject { }

            class ExampleObject: ExampleBarType { }

            class FooImplementation: Foo {
            typealias Bar = ExampleBarType
            func example<T: Bar>() -> T {
            return Bar.init() as! T
            }
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 22 '18 at 17:58









            E.ComsE.Coms

            2,1122414




            2,1122414













            • Yeah, this is currently the workaround I'm using, and it's exactly what I didn't wanted to do - to cast the return of my Type T -, but thanks for the tip.

              – Guilherme Matuella
              Nov 22 '18 at 18:21













            • What happens if I call let x: BarSubclass = foo.example()? I would expect that to crash. A Bar can't be as-cast to BarSubclass.

              – Rob Napier
              Nov 22 '18 at 22:55



















            • Yeah, this is currently the workaround I'm using, and it's exactly what I didn't wanted to do - to cast the return of my Type T -, but thanks for the tip.

              – Guilherme Matuella
              Nov 22 '18 at 18:21













            • What happens if I call let x: BarSubclass = foo.example()? I would expect that to crash. A Bar can't be as-cast to BarSubclass.

              – Rob Napier
              Nov 22 '18 at 22:55

















            Yeah, this is currently the workaround I'm using, and it's exactly what I didn't wanted to do - to cast the return of my Type T -, but thanks for the tip.

            – Guilherme Matuella
            Nov 22 '18 at 18:21







            Yeah, this is currently the workaround I'm using, and it's exactly what I didn't wanted to do - to cast the return of my Type T -, but thanks for the tip.

            – Guilherme Matuella
            Nov 22 '18 at 18:21















            What happens if I call let x: BarSubclass = foo.example()? I would expect that to crash. A Bar can't be as-cast to BarSubclass.

            – Rob Napier
            Nov 22 '18 at 22:55





            What happens if I call let x: BarSubclass = foo.example()? I would expect that to crash. A Bar can't be as-cast to BarSubclass.

            – Rob Napier
            Nov 22 '18 at 22:55













            0














            I'm not sure I'm fully understanding your use case but, isn't this enough for doing what you need to do?



            protocol Foo {
            associatedtype Bar
            func example() -> Bar
            }

            protocol BarProtocol { }

            class BarOne: BarProtocol { }

            class BarTwo: BarProtocol { }

            class FooImplementationOne: Foo {
            func example() -> BarProtocol {
            return BarOne()
            }
            }

            class FooImplementationTwo: Foo {
            func example() -> BarProtocol {
            return BarTwo()
            }
            }





            share|improve this answer
























            • Hey, thanks for answering. But no, this doesn't solve, mainly because I would always need to cast the return of example. Using your example for instance, the function FooImplementationOne example() function should return a BarOne instance, and FooImplementationTwo example() function should explicitly return a BarTwo instance. When you remove the generics from the example() function, it just knows that the type is BarProtocol meaning that I would've to cast everytime I wanted its type.

              – Guilherme Matuella
              Nov 22 '18 at 18:18


















            0














            I'm not sure I'm fully understanding your use case but, isn't this enough for doing what you need to do?



            protocol Foo {
            associatedtype Bar
            func example() -> Bar
            }

            protocol BarProtocol { }

            class BarOne: BarProtocol { }

            class BarTwo: BarProtocol { }

            class FooImplementationOne: Foo {
            func example() -> BarProtocol {
            return BarOne()
            }
            }

            class FooImplementationTwo: Foo {
            func example() -> BarProtocol {
            return BarTwo()
            }
            }





            share|improve this answer
























            • Hey, thanks for answering. But no, this doesn't solve, mainly because I would always need to cast the return of example. Using your example for instance, the function FooImplementationOne example() function should return a BarOne instance, and FooImplementationTwo example() function should explicitly return a BarTwo instance. When you remove the generics from the example() function, it just knows that the type is BarProtocol meaning that I would've to cast everytime I wanted its type.

              – Guilherme Matuella
              Nov 22 '18 at 18:18
















            0












            0








            0







            I'm not sure I'm fully understanding your use case but, isn't this enough for doing what you need to do?



            protocol Foo {
            associatedtype Bar
            func example() -> Bar
            }

            protocol BarProtocol { }

            class BarOne: BarProtocol { }

            class BarTwo: BarProtocol { }

            class FooImplementationOne: Foo {
            func example() -> BarProtocol {
            return BarOne()
            }
            }

            class FooImplementationTwo: Foo {
            func example() -> BarProtocol {
            return BarTwo()
            }
            }





            share|improve this answer













            I'm not sure I'm fully understanding your use case but, isn't this enough for doing what you need to do?



            protocol Foo {
            associatedtype Bar
            func example() -> Bar
            }

            protocol BarProtocol { }

            class BarOne: BarProtocol { }

            class BarTwo: BarProtocol { }

            class FooImplementationOne: Foo {
            func example() -> BarProtocol {
            return BarOne()
            }
            }

            class FooImplementationTwo: Foo {
            func example() -> BarProtocol {
            return BarTwo()
            }
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 22 '18 at 18:08









            Fabio FeliciFabio Felici

            1,102613




            1,102613













            • Hey, thanks for answering. But no, this doesn't solve, mainly because I would always need to cast the return of example. Using your example for instance, the function FooImplementationOne example() function should return a BarOne instance, and FooImplementationTwo example() function should explicitly return a BarTwo instance. When you remove the generics from the example() function, it just knows that the type is BarProtocol meaning that I would've to cast everytime I wanted its type.

              – Guilherme Matuella
              Nov 22 '18 at 18:18





















            • Hey, thanks for answering. But no, this doesn't solve, mainly because I would always need to cast the return of example. Using your example for instance, the function FooImplementationOne example() function should return a BarOne instance, and FooImplementationTwo example() function should explicitly return a BarTwo instance. When you remove the generics from the example() function, it just knows that the type is BarProtocol meaning that I would've to cast everytime I wanted its type.

              – Guilherme Matuella
              Nov 22 '18 at 18:18



















            Hey, thanks for answering. But no, this doesn't solve, mainly because I would always need to cast the return of example. Using your example for instance, the function FooImplementationOne example() function should return a BarOne instance, and FooImplementationTwo example() function should explicitly return a BarTwo instance. When you remove the generics from the example() function, it just knows that the type is BarProtocol meaning that I would've to cast everytime I wanted its type.

            – Guilherme Matuella
            Nov 22 '18 at 18:18







            Hey, thanks for answering. But no, this doesn't solve, mainly because I would always need to cast the return of example. Using your example for instance, the function FooImplementationOne example() function should return a BarOne instance, and FooImplementationTwo example() function should explicitly return a BarTwo instance. When you remove the generics from the example() function, it just knows that the type is BarProtocol meaning that I would've to cast everytime I wanted its type.

            – Guilherme Matuella
            Nov 22 '18 at 18:18













            0














            What you're designing here isn't possible to implement. This isn't a Swift problem; I mean it's literally not possible to implement because the types don't make the promises you need. Consider this part:



            class ExampleBarType {} // Not an NSObject subclass.

            class FooImplementation: Foo {
            typealias Bar = ExampleBarType

            func example<T: Bar>() -> T {
            // What would you write here?
            }
            }


            How do you plan to write that function body? Consider the following caller:



            class MyBar: Bar {        
            init(x: Int) {}
            }

            let ex: MyBar = foo.example()


            How would you implement example? How can you construct MyBar? You don't know the parameters for the init method (it requires an Int that you don't have). But your function signature claims that this function will return whatever specific subclass of Bar the caller requests.



            In general you should avoid mixing protocols, generics, and subclassing in the same type system. They pull in different directions and it is very difficult to keep your system coherent. You're going to wind up with a lot of cases where you can't fulfill your promises.



            You should go back to your concrete problem and need. If you're doing this "because I want to be as generic as possible," I recommend stopping. The Swift type system is very powerful, but also has some very tricky limitations, and "as generic as possible just because" almost always slams into those restrictions. If you have a concrete use case in a real program, however, you often (though not always) can avoid those headaches.






            share|improve this answer




























              0














              What you're designing here isn't possible to implement. This isn't a Swift problem; I mean it's literally not possible to implement because the types don't make the promises you need. Consider this part:



              class ExampleBarType {} // Not an NSObject subclass.

              class FooImplementation: Foo {
              typealias Bar = ExampleBarType

              func example<T: Bar>() -> T {
              // What would you write here?
              }
              }


              How do you plan to write that function body? Consider the following caller:



              class MyBar: Bar {        
              init(x: Int) {}
              }

              let ex: MyBar = foo.example()


              How would you implement example? How can you construct MyBar? You don't know the parameters for the init method (it requires an Int that you don't have). But your function signature claims that this function will return whatever specific subclass of Bar the caller requests.



              In general you should avoid mixing protocols, generics, and subclassing in the same type system. They pull in different directions and it is very difficult to keep your system coherent. You're going to wind up with a lot of cases where you can't fulfill your promises.



              You should go back to your concrete problem and need. If you're doing this "because I want to be as generic as possible," I recommend stopping. The Swift type system is very powerful, but also has some very tricky limitations, and "as generic as possible just because" almost always slams into those restrictions. If you have a concrete use case in a real program, however, you often (though not always) can avoid those headaches.






              share|improve this answer


























                0












                0








                0







                What you're designing here isn't possible to implement. This isn't a Swift problem; I mean it's literally not possible to implement because the types don't make the promises you need. Consider this part:



                class ExampleBarType {} // Not an NSObject subclass.

                class FooImplementation: Foo {
                typealias Bar = ExampleBarType

                func example<T: Bar>() -> T {
                // What would you write here?
                }
                }


                How do you plan to write that function body? Consider the following caller:



                class MyBar: Bar {        
                init(x: Int) {}
                }

                let ex: MyBar = foo.example()


                How would you implement example? How can you construct MyBar? You don't know the parameters for the init method (it requires an Int that you don't have). But your function signature claims that this function will return whatever specific subclass of Bar the caller requests.



                In general you should avoid mixing protocols, generics, and subclassing in the same type system. They pull in different directions and it is very difficult to keep your system coherent. You're going to wind up with a lot of cases where you can't fulfill your promises.



                You should go back to your concrete problem and need. If you're doing this "because I want to be as generic as possible," I recommend stopping. The Swift type system is very powerful, but also has some very tricky limitations, and "as generic as possible just because" almost always slams into those restrictions. If you have a concrete use case in a real program, however, you often (though not always) can avoid those headaches.






                share|improve this answer













                What you're designing here isn't possible to implement. This isn't a Swift problem; I mean it's literally not possible to implement because the types don't make the promises you need. Consider this part:



                class ExampleBarType {} // Not an NSObject subclass.

                class FooImplementation: Foo {
                typealias Bar = ExampleBarType

                func example<T: Bar>() -> T {
                // What would you write here?
                }
                }


                How do you plan to write that function body? Consider the following caller:



                class MyBar: Bar {        
                init(x: Int) {}
                }

                let ex: MyBar = foo.example()


                How would you implement example? How can you construct MyBar? You don't know the parameters for the init method (it requires an Int that you don't have). But your function signature claims that this function will return whatever specific subclass of Bar the caller requests.



                In general you should avoid mixing protocols, generics, and subclassing in the same type system. They pull in different directions and it is very difficult to keep your system coherent. You're going to wind up with a lot of cases where you can't fulfill your promises.



                You should go back to your concrete problem and need. If you're doing this "because I want to be as generic as possible," I recommend stopping. The Swift type system is very powerful, but also has some very tricky limitations, and "as generic as possible just because" almost always slams into those restrictions. If you have a concrete use case in a real program, however, you often (though not always) can avoid those headaches.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 22 '18 at 22:58









                Rob NapierRob Napier

                200k28296422




                200k28296422






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435863%2fassociatedtype-usage-inside-protocols-and-generic-functions%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    404 Error Contact Form 7 ajax form submitting

                    How to know if a Active Directory user can login interactively

                    TypeError: fit_transform() missing 1 required positional argument: 'X'