Swift 通用参数';S';无法推断

Swift 通用参数';S';无法推断,swift,generics,dependency-injection,Swift,Generics,Dependency Injection,因此,我尝试使用泛型和协议一致性来创建一个小型依赖项注入容器。但是我在编译它时遇到了一些麻烦 我想知道是否有一位敏捷的专家能告诉我问题出在哪里 import Foundation protocol Service: NSObjectProtocol { init() } protocol ServicesType { func add<S: Service>(service: S.Type) func get<S: Service>() thr

因此,我尝试使用泛型和协议一致性来创建一个小型依赖项注入容器。但是我在编译它时遇到了一些麻烦

我想知道是否有一位敏捷的专家能告诉我问题出在哪里

import Foundation

protocol Service: NSObjectProtocol {
    init()
}

protocol ServicesType {
    func add<S: Service>(service: S.Type)
    func get<S: Service>() throws -> S
}

class Services: ServicesType {

    var services: [Service.Type] = []

    func add<S: Service>(service: S.Type) {
        if services.contains(where: { service -> Bool in return service == service }) { return }
        services.append(service)
    }

    func get<S: Service>() throws -> S {
        guard let first = services.first(where: { service -> Bool in return service == service }) else { throw ServicesTypeError.notFound }
        return first.init() as! S
    }
}

enum ServicesTypeError: Error {
    case notFound
}

在操场上做了一点修改后,这个功能就可以正常工作了,但它似乎可以正常工作

如果我是对的(黑体字)

需要:

let creditCardService: **CreditCardService** = try self.services.get()
完整代码:

import Foundation

protocol Service: NSObjectProtocol {
    init()
}

protocol ServicesType {
    func add<S: Service>(service: S.Type)
    func get<S: Service>() throws -> S
}

class Services: ServicesType {

    var services: [Service.Type] = []

    func add<S: Service>(service: S.Type) {
        if services.contains(where: { service -> Bool in return service == service }) { return }
        services.append(service)
    }

    func get<S: Service>() throws -> S {
        guard let first = services.first(where: { service -> Bool in return service == service }) else { throw ServicesTypeError.notFound }
        return first.init() as! S
    }
}

enum ServicesTypeError: Error {
    case notFound
}

class CreditCard {

}

protocol CreditCardServiceType : Service {
    var cards: [CreditCard] { get }
}

class CreditCardService: NSObject, CreditCardServiceType {

    required override init() {
        super.init()
    }
    var cards: [CreditCard] = []
}

let services = Services()
services.add(service: CreditCardService.self)

let creditCardService: CreditCardService = try services.get()
<代码>导入基础 协议服务:NSObjectProtocol{ init() } 协议服务类型{ func添加(服务:S.Type) func get()抛出->S } 类别服务:ServicesType{ var服务:[服务.类型]=[] func添加(服务:S.Type){ if services.contains(其中:{service->Bool in return service==service}){return} services.append(服务) } func get()抛出->S{ guard let first=services.first(其中:{service->Bool in return service==service})else{throw ServicesTypeError.notFound} 首先将.init()返回为!S } } enum ServicesTypeError:错误{ 未发现病例 } 班级信用卡{ } 协议CreditCardServiceType:服务{ var卡:[信用卡]{get} } CreditCardService类:NSObject,CreditCardServiceType{ 必需的重写初始化(){ super.init() } 信用卡:[信用卡]=[] } 让服务=服务() services.add(服务:CreditCardService.self) 让creditCardService:creditCardService=try services.get()
好的,我的结论如下。虽然没有我想要的那么安全,但已经足够好了

import Foundation

protocol Service: NSObjectProtocol {
    init()
}

protocol ServicesType {

    func add<S: Service>(service: S.Type) throws
    func get<S>() throws -> S

}

class Services: ServicesType {

    var services: [Service.Type] = []

    func add<S: Service>(service: S.Type) throws {
        if services.contains(where: { existing -> Bool in return existing == service }) { throw ServicesTypeError.allReadyAdded}
        services.append(service)
    }

    func get<S>() throws -> S {
        guard let first = services.first(where: { existing -> Bool in return existing is S }) else { throw ServicesTypeError.notFound }
        return first.init() as! S
    }

}

enum ServicesTypeError: Error {
    case allReadyAdded
    case notFound
}

如果我将第一段代码粘贴到Playerd中,它在ServicesType上也会失败。还有更多吗?添加了代码的其余部分。我认为@tommysadiqhinrichsens仍然没有提供足够的代码。但出于测试原因,我想隐藏实现类,以便使用具有相同协议的另一个类。这是另一个问题@TommySadiqHinrichsen。让我想一想…@TommySadiqHinrichsen当你添加一个服务时,只需添加它而不需要类型。它应该只是一个实现。当你得到一个服务时,你只需要寻找一个实现该协议的服务。@TommySadiqHinrichsen你会很高兴将其标记为已回答(我得到它是通过推理编译的)。对于你想要的行为,提出一个不同的问题可能是值得的。谢谢这是一个有趣的问题。当然,我只需要让两天过去。
import Foundation

protocol Service: NSObjectProtocol {
    init()
}

protocol ServicesType {
    func add<S: Service>(service: S.Type)
    func get<S: Service>() throws -> S
}

class Services: ServicesType {

    var services: [Service.Type] = []

    func add<S: Service>(service: S.Type) {
        if services.contains(where: { service -> Bool in return service == service }) { return }
        services.append(service)
    }

    func get<S: Service>() throws -> S {
        guard let first = services.first(where: { service -> Bool in return service == service }) else { throw ServicesTypeError.notFound }
        return first.init() as! S
    }
}

enum ServicesTypeError: Error {
    case notFound
}

class CreditCard {

}

protocol CreditCardServiceType : Service {
    var cards: [CreditCard] { get }
}

class CreditCardService: NSObject, CreditCardServiceType {

    required override init() {
        super.init()
    }
    var cards: [CreditCard] = []
}

let services = Services()
services.add(service: CreditCardService.self)

let creditCardService: CreditCardService = try services.get()
import Foundation

protocol Service: NSObjectProtocol {
    init()
}

protocol ServicesType {

    func add<S: Service>(service: S.Type) throws
    func get<S>() throws -> S

}

class Services: ServicesType {

    var services: [Service.Type] = []

    func add<S: Service>(service: S.Type) throws {
        if services.contains(where: { existing -> Bool in return existing == service }) { throw ServicesTypeError.allReadyAdded}
        services.append(service)
    }

    func get<S>() throws -> S {
        guard let first = services.first(where: { existing -> Bool in return existing is S }) else { throw ServicesTypeError.notFound }
        return first.init() as! S
    }

}

enum ServicesTypeError: Error {
    case allReadyAdded
    case notFound
}
try self.services.add(service: ProfileService.self)
let profileService: ProfileServiceType = try self.services.get()