泛型参数'T'无法推断出。

4

我正在重构代码并且添加对Swift泛型的支持。但是我遇到了编译器错误。我的代码如下:

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)
}

这个编译很顺利。但是,当我尝试出列一个视图控制器时出现问题:

// Get view controller from the reuse queue.
let viewController: UIViewController = self.dequeueReusableViewController()

我遇到了一个错误:

无法推断通用参数 'T'

我该如何解决这个问题?我在stackoverflow上查看了类似的问题,但没有一个能够描述我的情况。


“let viewController = self.dequeueReusableViewController() as! UIViewController” 这段代码怎么样? - brduca
一样的事情,我得到了相同的错误。 - Rafał Sroka
强制将类型转换为泛型类型?返回 delegate!.reusableViewControllerForPageViewController(self) as! T。 - brduca
没有任何区别。当我添加了这个强制转换时,编译器会发出警告:将'T'强制转换为相同类型没有效果 - Rafał Sroka
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Joe
3个回答

5
调用返回泛型类型的泛型函数时,如果没有指定要分配给的变量的类型或将函数调用转换为某个类型,则无法推断类型。您可以这样做:
let viewController: SomeViewController = self.dequeueReusableViewController()

或者
let viewController = self.dequeueReusableViewController() as SomeViewController

我建议使用第一种选项,除非需要使用第二种(例如需要分配给可选项)。


谢谢回答!我尝试了 let viewController: UIViewController = self.dequeueReusableViewController(),但是我得到了完全相同的错误。 - Rafał Sroka
这是因为单独的 UIViewController 没有实现 Reusable - ahaese

2

编译器不可能像你一样推断出T类型,因为你没有提供足够的信息。

你可以让方法知道T的类型:

func dequeueReusableViewController<T: UIViewController where T: Reusable>(type: T.Type) -> T?

// ...

let viewController = self.dequeueReusableViewController(YourViewController)

或者更简洁的做法是让变量来完成这项工作:

func dequeueReusableViewController<T: UIViewController where T: Reusable>() -> T?

// ...

let viewController: YourViewController = self.dequeueReusableViewController()

无论哪种方式,您都需要提供一些帮助,让编译器知道您正在处理什么。


0

如果您使用以下示例,应该可以正常工作

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)

泛型 -

let viewController = self.dequeueReusableViewController() 

只是将值存储在viewController中,但viewController的类型未知,因此它显示了“无法推断泛型参数'T'”

尝试使用let viewController: UIViewController = self.dequeueReusableViewController()

然后T将从UIViewController类型中推断出来。


谢谢回答!我尝试了 let viewController: UIViewController = self.dequeueReusableViewController(),但是我得到了完全相同的错误。 - Rafał Sroka
确保UIViewController也符合可重用性。 - Rahul Katariya
添加了一个快速示例。 - Rahul Katariya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接