【问题标题】:Return struct type confirming to protocols返回结构类型确认协议
【发布时间】:2018-04-27 10:44:29
【问题描述】:

这是我的一段代码,

protocol Configuration {

    static var url: String { get }
    static var username: String { get }
    static var password: String { get }
}

protocol Server {

    associatedtype Profile: Configuration
    associatedtype Payment: Configuration
    associatedtype Images: Configuration
}

struct Development: Server {

    struct Profile: Configuration {

        static var url: String { return "http://google.com" }
        static var username: String { return "abc" }
        static var password: String { return "xyz" }
    }

    struct Payment: Configuration {

        static var url: String { return "http://bing.com" }
        static var username: String { return "abc" }
        static var password: String { return "xyz" }
    }

    struct Images: Configuration {

        static var url: String { return "http://duckduckgo.com" }
        static var username: String { return "abc" }
        static var password: String { return "xyz" }
    }
}

struct Production: Server {

    struct Profile: Configuration {

        static var url: String { return "http://amazon.com" }
        static var username: String { return "pqr" }
        static var password: String { return "xyz" }
    }

    struct Payment: Configuration {

        static var url: String { return "http://facebook.com" }
        static var username: String { return "pqr" }
        static var password: String { return "xyz" }
    }

    struct Images: Configuration {

        static var url: String { return "http://orkut.com" }
        static var username: String { return "pqr" }
        static var password: String { return "xyz" }
    }
}

问题是我想获取我的“结构”(取决于我的环境)。我需要类似的东西,

struct Environment {

    static func current() -> Any:Server {

        if #DEBUG
            return Development
        #endif

        return Production
    }
}

但是返回特定类型以确认我的协议是不可能的。

对此或不同方法的任何建议都会有所帮助。

【问题讨论】:

  • 你想让 current() 返回结构类型吗?不是结构的实例?
  • @andlin 是的,那么只有我可以在其中使用静态属性,

标签: swift struct protocols


【解决方案1】:

“开发”和“生产”是值,而不是类型。您在这里不需要协议,也不应该使用它们。只需创建您需要的值并返回它们:

struct Server {
    let url: String
    let username: String
    let password: String
}

struct Environment {
    let profile: Server
    let payment: Server
    let images: Server

    static let development = Environment(
        profile: Server(url: "http://google.com", username: "abc", password: "xyz"),
        payment: Server(url: "http://bing.com", username: "abc", password: "xyz"),
        images: Server(url: "http://duckduckgo.com", username: "abc", password: "xyz")
    )

    static let production = Environment(...)

    static var current: Environment {
        #if DEBUG
            return development
        #else
            return production
        #endif
    }
}

【讨论】:

  • 已编辑以进一步简化它。三级结构没有理由;只有两个。
【解决方案2】:

您可以返回一个泛型类型,也可以简单地执行以下操作:

struct Config {

  static var BaseURL: URL {
    switch Environment.current {
      case .debug:
        return URL(string: "https://...dev.com")!
      case .staging:
        return URL(string: "https://...staging.com")!
      case .release:
        return URL(string: "https://...production.com")!
      }
  }

}

【讨论】:

    【解决方案3】:

    只返回Server,而不是Any:Server

    static func current() -> Server {
    
        if #DEBUG
            return Development
        #endif
    
        return Production
    }
    

    【讨论】:

    • 服务器是一个协议。错误:协议“服务器”只能用作通用约束,因为它具有自身或关联的类型要求
    • 同意这不会解决它,但 Andreas 是正确的,Any: Server(对于任何协议,不仅仅是Server)总是错误的。你不能仅仅通过在其中抛出“Any”来避免“通用约束”问题。
    猜你喜欢
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    相关资源
    最近更新 更多