问题
I'm refactoring my code and adding support for Swift generics. I'm stuck with a compiler error. My code is:
func dequeueReusableViewController<T: UIViewController where T: Reusable>() -> T {
// Try to fetch view controller from the reuse queue.
if !self.viewControllerReuseQueue.isEmpty {
return self.viewControllerReuseQueue.popFirst()! as! T
}
// Ask delegate to instantiate a new view controller.
return delegate!.reusableViewControllerForPageViewController(self)
}
This compiles smoothly. Then, later, when I try to dequeue a view controller:
// Get view controller from the reuse queue.
let viewController: UIViewController = self.dequeueReusableViewController()
I'm getting an error:
Generic parameter 'T' could not be inferred
How can I solve this? I checked similar questions on SO but none of them describes my case.
回答1:
The type cannot be inferred when calling a generic function returning a generic type without specifying the type of the variable you are assigning to or casting the call to the function. You can do:
let viewController: SomeViewController = self.dequeueReusableViewController()
or
let viewController = self.dequeueReusableViewController() as SomeViewController
I would recommend the first option unless the second is required (needing to assign to an optional for example).
回答2:
There is no way the compiler know what type T is as you do not infer it.
You could force the method to know about type T:
func dequeueReusableViewController<T: UIViewController where T: Reusable>(type: T.Type) -> T?
// ...
let viewController = self.dequeueReusableViewController(YourViewController)
Alternatively, and somewhat neater you could let the variable do the work:
func dequeueReusableViewController<T: UIViewController where T: Reusable>() -> T?
// ...
let viewController: YourViewController = self.dequeueReusableViewController()
Either way you need to provide some help to let the compiler know what you're dealing with.
回答3:
Should work if you are using like below example
protocol Reusable {
func someMethod()
}
class VC: UIViewController, Reusable {
func someMethod() {
//Implement
}
}
class Dequeuer {
var viewControllerReuseQueue = [VC(),VC(),VC()]
func dequeueReusableViewController<T: UIViewController where T: Reusable>() -> T? {
// Try to fetch view controller from the reuse queue.
return viewControllerReuseQueue.first as? T
}
}
let vc: VC? = Dequeuer().dequeueReusableViewController()
print(vc)
GENERICS -
let viewController = self.dequeueReusableViewController()
is just storing the value in viewController but the type of viewController is unknown thats why it is showing you Generic parameter 'T' could not be inferred
Try let viewController: UIViewController = self.dequeueReusableViewController()
Then T will get inferred from the type UIViewController.
来源:https://stackoverflow.com/questions/35157253/generic-parameter-t-could-not-be-inferred