What's the difference between using or not using the 'where' clause with generics?

前端 未结 2 1857
醉话见心
醉话见心 2020-12-10 13:49

What\'s the difference between these two methods of declaring a generics superclass with or without the \'where\' clause?

func foo(object         


        
2条回答
  •  余生分开走
    2020-12-10 14:10

    Questions like these always require some practical examples, even the simplest to get basic idea. Otherwise it often remains theoretical.

    As referenced by Sweeper, that which is after where is called type constraint. Typically you specify one or more protocols which introduce conditions which must be met by passed object or a type. And as mentioned, it's only after where where you can specify associatedtype constraint of the generic type.

    Consider the following example:

    protocol MyProtocol {
        associatedtype AType
    
        func foo()
    }
    
    class MyClassInt : NSObject, MyProtocol {
        typealias AType = Int
    
        func foo() {
            print(type(of: self))
        }
    }
    
    class MyClassString : NSObject, MyProtocol {
        typealias AType = String
    
        func foo() {
            print("I'm not implemented")
        }
    }
    
    extension MyProtocol where Self.AType == Int {
        func test() {
            self.foo()
        }
    }
    

    Now check our things:

    let str = MyClassString()
    str.test() // Won't compile !! 
    

    'MyClassString.AType' (aka 'String') is not convertible to 'Int'

    This one compiles and runs:

    let int = MyClassInt()
    int.test()
    

    In this example we have a protocol with the associatedtype specified. And there's also an extension which is only applied to our MyProtocol with particular associatedtype, in our case Int. That extension defines single method. As you can see, compiler won't let us to call that method with the associatedtype other than that specified by a constraint, even though MyClassString also implements that protocol.

提交回复
热议问题