代码之家  ›  专栏  ›  技术社区  ›  graydam

我们能在swift上重用struct吗?还是有别的办法?

  •  1
  • graydam  · 技术社区  · 7 年前

    所以我有一个用户json结构,如下所示:

    - results: {
        meta: {}
        users: []
      },
    - status:
    

    我想让用户 User 我实现的获取json的模型如下:

    struct Response: Decodable {
    
        let results: Result
        let status: Int
    }
    
    struct Result: Decodable {
    
        let meta: Meta
        let users: [User]
    }
    
    struct Meta: Decodable {
    
        let total_data: Int
        let total_page: Int
    }
    
    struct User: Decodable {
    
        let avatar_url: String
        let created_at: String
        let updated_at: String
        let email: String
        let id: Int
        let name: String
        let username: String
    }
    

    它可以工作,但是当我有另一个结构类似的json时,可以这样说

    - results: {
            meta: {}
            rooms: []
          },
        - status:
    

    当我创造 Room 模型,与另一个 struct Response 在它上面,它将导致错误,因为它是重复的声明。

    是否可以在swift中重用struct?或者有什么方便的方法吗?

    谢谢

    4 回复  |  直到 7 年前
        1
  •  8
  •   pstued    7 年前

    你可以用泛型。

    struct Response<T: Decodable>: Decodable {
        let results: Result<T>
        let status: Int
    }
    
    struct Result<T: Decodable>: Decodable {
        let meta: Meta
        let objects: [T]
    }
    
    struct Meta: Decodable {    
        let total_data: Int
        let total_page: Int
    }
    
    struct User: Decodable {
        let avatar_url: String
        let created_at: String
        let updated_at: String
        let email: String
        let id: Int
        let name: String
        let username: String
    }
    
    let userResponse: Response<User>?
    
        2
  •  2
  •   luk2302    7 年前

    您可以尝试以下方式使用泛型:

    struct Response<ResultType> : Decodable where ResultType : Decodable {
        let results: ResultType
        let status: Int
    }
    

    然后使用该结构通过:

    struct Result: Decodable {
        let something: String
    }
    
    let decoder = JSONDecoder()
    let data = "{\"status\":123,\"results\":{\"something\":\"hi\"}}".data(using: .utf8)!
    let value = try! decoder.decode(Response<Result>.self, from: data) // will be of type Response<Result>
    
        3
  •  1
  •   Prashant Tukadiya    7 年前

    你有一个选择就是重复使用 Meta Status 如果你用山猫

    对于用户,可以替换名称

    struct UserResult: Decodable {
    
        let meta: Meta
        let users: [User]
    }
    
    struct UserResponse: Decodable {
    
        let results: UserResult
        let status: Int
    }
    

    还有房间

    struct RoomResult: Decodable {
    
        let meta: Meta
        let users: [Room]
    }
    
    struct RoomResponse: Decodable {
    
        let results: RoomResult
        let status: Int
    }
    
        4
  •  1
  •   Jeffery Thomas    7 年前

    根据需要,可以使用泛型来组成整个结构。

    从数据模型开始

    struct User: Decodable {
        let avatar_url: String
        let created_at: String
        let updated_at: String
        let email: String
        let id: Int
        let name: String
        let username: String
    }
    
    struct Room: Decodable {
        let id: Int
        let name: String
    }
    

    我们的目标是得到好的组合类型。

    typealias UserResponse = Response<Result<User, Meta>>
    typealias RoomResponse = Response<Result<Room, Meta>>
    

    要从中生成的泛型类型

    struct Response<ResultType: Decodable>: Decodable {
        let results: ResultType
        let status: Int
    }
    
    struct Result<ItemType: Decodable, MetaType: Decodable>: Decodable {
        let meta: MetaType
        let items: [ItemType]
    }
    

    偶数 Meta 是构成的一个独立部分。

    struct Meta: Decodable {
        let total_data: Int
        let total_page: Int
    }
    

    现在假设我们需要一个自定义 对于 Room 响应

    struct PagedMeta: Decodable {
        let current_page: Int
        let page_count: Int
    }
    

    这是新型的

    typealias RoomPagedResponse = Response<Result<Room, PagedMeta>>
    
    推荐文章