【问题标题】:Can I compose types in Swift?我可以在 Swift 中编写类型吗?
【发布时间】:2019-08-15 12:32:12
【问题描述】:

如何在 Swift 中编写类似于协议组合的类型?

例如,我有一个 likes 数据,它是一个字典,其值具有 IntString,但没有其他值。

likes: {
    "1": {
        "id": "l1"
        "ts": 1551796878504
        "userId": "u1"
    }
}

当前,我使用一个带类型的变量,

var likes: [String: [String: Any]]

但是,我希望它是类型

var likes: [String: [String: AlphaNum]]

我可以使用typealias AlphaNum = String & Int 或类似的东西,而不使用类或结构吗?

【问题讨论】:

  • 您的意思可能是String | Int,这在动态类型语言中会很好。这在 Swift 中是不可能的。您应该将值包装到自定义结构或具有关联值的枚举中。

标签: swift types composition


【解决方案1】:

您可以创建自己的协议并让StringInt 符合它:

protocol ValueProtocol {}

extension String:ValueProtocol{}
extension Int:ValueProtocol{}


var likes:[String : [String:ValueProtocol]] = ["1": [
                    "id": "l1",
                    "ts": 1551796878504,
                    "userId": "u1"
                ]
            ]

但要使用 ValueProtocols,您还必须根据需要向其中添加 getValue 之类的函数。

【讨论】:

    【解决方案2】:

    不,你不能,你可以看到 typealias AlphaNum = String & Int 它是 & 运算符而不是 | \\ or 并且你不能使用 [String: [String: AlphaNum]] 因为内部 Dictionary 值基本上是 String & Int ,一个值可以'不是两种类型中的任何一种,看看这个question,因为答案是关于创建一个虚拟协议,并使用它但是IntString之间没有共享属性,但是一个Description ,因此即使使用虚拟protocol,您也必须在某些时候进行转换,除非您仅使用Description 指代answer

     protocol IntOrString {
        var description: String { get }
    }
    
    extension Int : IntOrString {}
    extension String : IntOrString {}
    

    像这样使用它,var likes: [String: [String: IntOrString]]

    进入IntOrString 值后,您可以使用.description 属性。

    【讨论】:

      【解决方案3】:

      我知道这个问题已经得到解答,但在我看来,您正在尝试使用 JSON,因此我强烈建议您在 swift 中使用 Decodableprotocol

      Decodable:可以从外部表示docs解码自身的类型

      这将轻松处理所有传入的 JSON,例如:

      struct decodableIncomming: Decodable {
        let name: String
        let ID: Int
        let externalURL: URL
      }
      
      let json = """
      {
       "name": "Robert Jhonson",
       "ID": 1234256,
       "externalURL": "http://someurl.com/helloworld"
      }
      """.data(using: .utf8)! // data in JSON which might be requested from a url
      
      let decodedStruct = try JSONDecoder().decode(Swifter.self, from: json) // Decode data
      print(decodedStruct) //Decoded structure ready to use
      

      【讨论】:

      • +1 表示可解码。在此示例中,我没有直接使用 JSON。但这些信息肯定会有所帮助。
      • 好的,希望对您有所帮助,如果您曾经使用 JSON decodable 是我迄今为止发现的最佳方式。
      猜你喜欢
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 2020-06-15
      • 1970-01-01
      • 2016-04-19
      • 2017-12-13
      • 1970-01-01
      相关资源
      最近更新 更多