Generics in Swift - "Generic parameter 'T' could not be inferred

前端 未结 3 1865
有刺的猬
有刺的猬 2020-12-08 03:46

I\'d like to return a UIViewController conforming to MyProtocol from a method, so I\'m using the method signature:

func myMethod<         


        
3条回答
  •  萌比男神i
    2020-12-08 04:43

    In a method like this, returning T means you have to return T. If you return MyViewController, the return type should be MyViewController. T is a generic type that will take the form of whatever the Swift compiler can infer it to be.

    So, with your method signature, a simple implementation of the protocol and method could look like this.

    protocol MyProtocol {
        var name: String { get set }
    }
    
    func myMethod() -> T {
        var vc = T()
        vc.name = "Hello, world"
        return vc
    }
    

    So, considering your usage example:

    let x = myMethod()
    

    How would the compiler know what the concrete type of T is? There is nothing giving it a hint of MyViewController. The only thing we know is that whatever T is, it should be MyViewController or a subclass of it. And it should conform to MyProtocol. But this does not provide information about what the type of T should be.

    The only place where the compiler can infer what we want T to be is through the return value. All the code between <> are constraints for what T is allowed to be. -> T is the only place where T is seen outside of the constraints. So if we can somehow tell the compiler what we want myMethod to return, we have given it enough information to infer T.

    Your typecast works but I agree that it's not very pretty. A much prettier way for the compiler to infer T is this.

    let vc: MyViewController = myMethod()
    

    By specifying the type of vc, the compiler understands that we want myMethod to return a MyViewController. So now T's type can be inferred and if we return T, we actually return MyViewController.

提交回复
热议问题