【问题标题】:Swift. Internal type in public protocol迅速。公共协议中的内部类型
【发布时间】:2018-04-17 15:49:52
【问题描述】:

我正在尝试使用 swift 泛型,但我被卡住了...
这样做可能是不可能的,但我希望有人能提出一个好的建议。

所以我有这个协议和一个我想要内部的类型:

internal protocol ATCoreInstrumentProtocol { // SOME STUFF }
internal typealias AT_1G_WaveInstrumentType = //Somethings that conforms to ATCoreInstrumentProtocol

然后我就有了我想要公开的 InstrumentType。 这里的问题是ASSOCIATED_INSTRUMENT又名ATCoreInstrumentProtocol 需要internal,因此我不能以这种方式使用它。 没有将ATCoreInstrumentProtocol 公开的选项。

public protocol InstrumentType {
  static var instrumentType: SupportedInstrumentTypes { get }
  associatedtype ASSOCIATED_INSTRUMENT: ATCoreInstrumentProtocol
}

public final class InstrumentTypes {
  private init() {}

  public final class AT_1G_Wave : InstrumentType {
      public class var instrumentType: SupportedInstrumentTypes { get { return .wave_1G } }
      public typealias ASSOCIATED_INSTRUMENT = AT_1G_WaveInstrumentType
  }
}

这就是我想要使用它的方式。

internal class ATCoreInteractor<IT: InstrumentType> {

  internal var instrumentObservable : Observable<IT.ASSOCIATED_INSTRUMENT> {
      return self.instrumentSubject.asObservable()
  }

  private var instrumentSubject = ReplaySubject<IT.ASSOCIATED_INSTRUMENT>.create(bufferSize: 1)

  internal init(withSerial serial: String){
      self.scanDisposable = manager
          .scanFor([IT.instrumentType])
          .get(withSerial: serial)
          .take(1)
          .do(onNext: { (inst) in
              self.instrumentSubject.onNext(inst)
          })
          .subscribe()
}

然后我有ATSyncInteractor,即public

public final class ATSyncInteractor<IT : InstrumentType> : ATCoreInteractor<IT> {
  public override init(withSerial serial: String) {
      super.init(withSerial: serial)
  }
}

public extension ATSyncInteractor where IT : InstrumentTypes.AT_1G_Wave {
  public func sync(opPriority: BLEOperationPriority = .normal, from: Date, to: Date, callback: @escaping (ATCoreReadyData<AT_1G_Wave_CurrentValues>?, [WaveTimeSeriesCoordinator], Error?) -> Void) {
    // DO SOMETHING
  }
}



let interactor = ATSyncInteractor<InstrumentTypes.AT_1G_Wave>(withSerial: "12345")

【问题讨论】:

  • 如果不知道ATCoreInstrumentProtocol,不同模块中的类型如何实现InstrumentType
  • @zneak 他们不打算实现它,但他们应该像这样使用它:let interactor = ATSyncInteractor&lt;InstrumentTypes.AT_1G_Wave&gt;(withSerial: "12345")
  • ATCoreInstrumentProtocol 也有关联类型吗?
  • @zneak 不,没有。
  • ATCoreInteractor 上的泛型参数在函数签名中有很大的意义吗?例如,您是否有接受ATSyncInteractor&lt;InstrumentTypes.AT_1G_Wave&gt;而不是ATSyncIterator&lt;IT&gt;(其中IT是泛型)的函数?

标签: ios swift generics swift-protocols associated-types


【解决方案1】:

这最终成为了我的解决方案..
InstrumentType 仅包含 SupportedInstrumentTypes
ATCoreInteractor 不再是通用的,但观察者的类型是 ATCoreInstrumentProtocol
ATSyncInteractor 扩展将仪器转换为其关联类型。

我愿意接受改进和建议。

public protocol InstrumentType : class {
    static var instrumentType: SupportedInstrumentTypes { get }
}

public final class InstrumentTypes {
    private init() {}

    public final class AT_1G_Wave : InstrumentType {
        private init() {}
        public class var instrumentType: SupportedInstrumentTypes { get { return .wave_1G } }
    }
}

public class ATCoreInteractor {

    internal var instrumentSubject = ReplaySubject<ATCoreInstrumentProtocol>.create(bufferSize: 1)

    internal init(for type: SupportedInstrumentTypes, withSerial serial: String){

        self.scanDisposable = manager
            .scanFor([type])
            .get(withSerial: serial)
            .take(1)
            .do(onNext: { (inst) in
                self.instrumentSubject.onNext(inst)
            })
            .subscribe()
    }
}

public final class ATSyncInteractor<IT : InstrumentType> : ATCoreInteractor {

    public init(withSerial serial: String) {
        super.init(for: IT.instrumentType, withSerial: serial)

    }
} 

public extension ATSyncInteractor where IT : InstrumentTypes.AT_1G_Wave {

    private func instrument() -> Observable<AT_1G_WaveInstrumentType> {
        return self.instrumentSubject.map { $0 as! AT_1G_WaveInstrumentType }
    }

    public func sync(opPriority: BLEOperationPriority = .normal, from: Date, to: Date, callback: @escaping (ATCoreReadyData<AT_1G_Wave_CurrentValues>?, [WaveTimeSeriesCoordinator], Error?) -> Void) {

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 2020-08-16
    • 2018-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多