创建返回泛型的工厂方法

Creating a factory method returning generic

我有一个摘要class这样定义:

class BaseCoordinator<ResultType>

其他类继承自这一个eg.

final class AppCoordinator: BaseCoordinator<Void>
final class AuthFlowCoordinator: BaseCoordinator<AuthFlowCoordinationResult>
final class MainFlowCoordinator: BaseCoordinator<Void>

现在我想创建一个 factory 方法。我想它的签名应该是这样的:

func makeCoordinator<T>() -> BaseCoordinator<T>

但是,当然,我会遇到这样的错误:

Cannot convert return expression of type 'AppCoordinator' to return type 'BaseCoordinator<T>'

Xcode 建议我添加 as! BaseCoordinator<T>,但我讨厌这种强制向下转换(并且返回 ? 也不能让我满意,因为我 100% 确定我将有一个正确的默认对象),因为我希望确保 至少 将返回一个默认值 Coordinator
感觉就像我错过了什么,但我真的不知道那是什么。是否真的可以制作这样的工厂方法,或者 Swift 泛型是否受限?

您可能想尝试 as? 而不是 as!。前者产生一个可选的,我。 e.如果转换不成功,结果将为 nil。这样你就可以安全地进行转换,而无需强制执行任何操作。

T 必须在编译时有一个预定义的类型。因此,您不能通过返回具有不同 ResultType 的不同协调器来使用 makeCoordinator() 的实现来选择 T

在这种情况下,调用者可以选择要分配给 T 的值,这可能会破坏函数。例如,以下两个调用将是完全有效的:

let coordinator: BaseCoordinator<Void> = makeCoordinator()
let coordinator: BaseCoordinator<[Int: [String]]> = makeCoordinator()

[Int: [String]] 用作通用类型没有意义,但它仍然是可能的。根据您在函数调用时选择的泛型类型,转换可能有效或无效,这就是强制转换可能导致崩溃的原因。

按照 Tom E 的建议,可选的强制转换可以解决潜在的崩溃问题,但仍然无法解决此问题。

因此,如果不使用包装类型擦除 ResultTypeAny,您就不能为此使用工厂模式,这将破坏泛型的目的。

如果你想要类型安全,你必须为你想要实例化的 BaseCoordinator 的每个子类创建一个工厂方法,或者只是手动调用它们的初始化器。