简体   繁体   English

无法推断通用参数“ S”

[英]Generic parameter 'S' could not be inferred

So I'm trying to make a small dependency injection container using generics and protocol conformance. 因此,我试图使用泛型和协议一致性来制作一个小的依赖项注入容器。 However i'm having some trouble compiling it. 但是我在编译时遇到了一些麻烦。

I wonder if there is a swift expert that can tell me what the problem is. 我想知道是否有一个敏捷的专家可以告诉我问题出在哪里。

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
}

Generic parameter 'S' could not be inferred is the error message when i try to compile the line below 当我尝试编译以下行时,无法推断出通用参数“ S”是错误消息

let creditCardService: CreditCardServiceType = try self.services.get()

protocol CreditCardServiceType : Service {
    var cards: [CreditCard] { get }
}
class CreditCardService: CreditCardServiceType {
    internal required init() {}
    var cards: [CreditCard] = []
}

It took a little modification to get this working in a Playground, but this seems to work. 经过一些修改,才能在Playground中运行此功能,但这似乎可行。

If I'm right (in bold), 如果我是对的(粗体),

let creditCardService: **CreditCardServiceType** = try self.services.get()

Needs to be: 需要是:

let creditCardService: **CreditCardService** = try self.services.get()

Full code: 完整代码:

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()

Ok what i ended up with is the following. 好吧,我最终得到的是以下内容。 Not as type safe as i wanted but good enough. 不是我想要的类型安全,但足够好。

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
}

usage: 用法:

try self.services.add(service: ProfileService.self)
let profileService: ProfileServiceType = try self.services.get()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM