【问题标题】:Generic protocol Swift 4 error通用协议 Swift 4 错误
【发布时间】:2017-10-10 19:49:45
【问题描述】:

以下代码在 Swift 3.2 上可以为我工作,但在 Swift 4 的最新版本中,我遇到了一个我无法理解的奇怪错误。

我正在尝试创建一个像这样的通用协议:

public protocol FactoryComponent {
  associatedtype Argument
  associatedtype Service
  static var factory: (Resolver) -> (Argument) -> Service { get }
}

public extension FactoryComponent {
    public typealias Factory = (Argument) -> Service
}

在这里使用它:

public extension Container {
  @discardableResult
  public func register<Component: FactoryComponent>(
    factory componentType: Component.Type
  ) -> ServiceEntry<Component.Factory> { // On this line the error shows
    return self.register(componentType.Factory.self) { resolver in
      componentType.factory(resolver)
    }
  }
}

错误:

“组件”没有名为“工厂”的成员类型;您是说“工厂”吗?

当然,自动修复也无济于事,因为错误是无用的......

我检查了 Swift 4 的重大更改,没有看到任何涉及通用协议的内容。

有人能帮我理解这是什么意思吗?

【问题讨论】:

  • 一个独立的示例会很有帮助。

标签: ios iphone swift generics


【解决方案1】:

似乎缺少FactoryComponent 的具体类。 Factory 类型别名只能由协议的具体类调用。

  1. 尝试创建一个实现其协议的FactoryComponent 具体类
  2. Argument 和 Service 在您的实现中仍然是通用的,需要具体类型。我的英语很糟糕,但我希望我对你有所帮助。如果我的答案不清楚,请查看下面的代码。

```

class Resolver {}

protocol FactoryComponent {
  associatedtype Argument
  associatedtype Service
  static var factory: (Resolver) -> (Argument) -> Service { get }
}

extension FactoryComponent {
  typealias Factory = (Argument) -> Service
}

class ConcreteFactoryComponent: FactoryComponent {
  static var factory: (Resolver) -> Factory {
    return foo
  }

  static func foo(_ resolver: Resolver) -> Factory {
    let factory: Factory = { argument in return "" }
    return factory
  }

  typealias Argument = String
  typealias Service = String
}

let factory: ConcreteFactoryComponent.Factory = { argument in return "" }

```

【讨论】:

    【解决方案2】:

    我相信错误与返回类型并不真正相关。由于 @escaping 的新默认值,Swift 4 中通用签名解析的处理略有改变。函数调用 self.register 函数,其签名与函数本身相同,这一事实可能是问题的根源。

    从其他类似的情况来看,我建议查看 Container.register 的签名。如果它碰巧有一个@escaping 闭包,那么扩展中泛型函数的签名也应该有一个,以便将其识别为重载。

    看到这个帖子:https://stackoverflow.com/a/43081214/5237560

    [编辑] 我刚刚意识到这种变化是在 Swift 2 和 3 之间。把答案留在这里,以防它可以提供一些灵感。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多