【问题标题】:Returning a protocol with associatedtype from another protocol API从另一个协议 API 返回具有关联类型的协议
【发布时间】:2022-11-27 11:34:35
【问题描述】:

我有一个 Session 协议和一个 Output 关联类型:

public protocol SessionAPI {
  associatedtype Output: Equatable
  var output: Output { get }
}

以及返回 String 的协议的具体实现:

public final class StringSession: SessionAPI {
  public typealias Output = String
  public let output: String
}

假设 StringSession 的实现非常复杂并且涉及许多模块,并且我不想向使用 SessionAPI 的类中的那些模块添加依赖项。所以我有另一个使用通用工厂方法出售 StringSessions 的协议:

public protocol SessionFactoryAPI {
  func createStringFactory<T: SessionAPI>() -> T where T.Output == String
}

所有这些都编译得很好。但是,当我尝试实现工厂 API 时,出现编译错误:

公共最终类 SessionFactory:SessionFactoryAPI { public func createStringFactory<T: SessionAPI>() -> T where T.Output == String { // 错误:无法将“StringSession”类型的值转换为预期的参数类型“T” 返回字符串会话() } }

有没有人对如何让它工作有任何建议?

【问题讨论】:

  • 您能否提供有关如何实现工厂 API 的详细信息?

标签: swift generics protocols


【解决方案1】:

错误:无法将“StringSession”类型的值转换为预期的参数类型“T”返回

意味着编译器不知道T应该是SessionAPI

SessionFactoryAPI

public protocol SessionFactoryAPI {
  func createStringFactory<T: SessionAPI>() -> T where T.Output == String
}

你只是指定T.Output应该是什么(即String

您可以尝试使用关联类型而不是通用函数来使用:

public protocol SessionFactoryAPI {
    associatedtype T: SessionAPI where T.Output == String
    func createStringFactory() -> T
}

struct MyFactory: SessionFactoryAPI {
    func createStringFactory() -> StringSession {
        .init(output: "output")
    }
}

您可以毫无错误地使用您的工厂 API:

let factory = MyFactory()
let stringSession: StringSession = factory.createStringFactory()
print(stringSession.output)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多