func myMethod<T where T : UIViewController, T : MyProtocol>() -> T
This declaration says: There exists a function called myMethod
, such that myMethod
returns some specific T
where T
is a subtype of UIViewController
and also MyProtocol
. This does not say what type T
actually is, and it does not say that there is only one such myMethod
. There can be many if there are many type that are both subclasses of UIViewController
and conform to MyProtocol
. Every one of those types creates a new version of myMethod
(really a new solution to the assertion myMethod
makes, that such a function does exist).
This is not the same thing as:
func myMethod() -> UIViewController
That says: The function myMethod
returns any subtype of UIViewController
.
There is no way in Swift to express "any type that is a subclass of UIViewController and is a subtype of MyProtocol." You can only discuss a specific type that meets that criterial. Swift can't combine classes and protocols this way; it's just a current limitation of the language, not a deep design issue.
The specific versus any is the issue. There are many functions that satisfy your myMethod
declaration. Every T
you can plug in that conforms to the rules would be a candidate. So when you say myMethod()
, the compiler doesn't know which specific T
you mean.
(I was going to expand this answer to provide it in less type-theory, more "how do you do it in code" terms, but donnywals already has an excellent version of that.)
* To your edited question *
func myMethod<T>() -> T where T : UIViewController, T : MyProtocol {
return MyViewController() as! T // why is the cast necessary?
}
T
is a specific type decided by the caller. It is not "any type that conforms" it is "some specific, concrete type that conforms." Consider the case that you called:
let vc: SomeOtherViewController = myMethod()
In this case, T
is SomeOtherViewController
. MyViewController
is not that type, so what you're doing with the as!
cast is dangerous.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…