GVKun编程网logo

Swift结构:为单个属性处理多种类型(swift构造方法)

10

在本文中,您将会了解到关于Swift结构:为单个属性处理多种类型的新资讯,同时我们还将为您解释swift构造方法的相关在本文中,我们将带你探索Swift结构:为单个属性处理多种类型的奥秘,分析swif

在本文中,您将会了解到关于Swift结构:为单个属性处理多种类型的新资讯,同时我们还将为您解释swift构造方法的相关在本文中,我们将带你探索Swift结构:为单个属性处理多种类型的奥秘,分析swift构造方法的特点,并给出一些关于10.4 Swift结构体中的mutating方法、12.6 Swift结构体的构造方法、5.3 Swift的结构(struct)类型及其下标(subscript) [Swift原创教程]、8.1 Swift结构体定义的实用技巧。

本文目录一览:

Swift结构:为单个属性处理多种类型(swift构造方法)

Swift结构:为单个属性处理多种类型(swift构造方法)

我正在使用Swift 4并尝试解析一些JSON数据,这些数据显然在某些情况下对于同一键可能具有不同的类型值,例如:

{    "type": 0.0}

{    "type": "12.44591406"}

我实际上坚持定义我的名字,struct因为我不知道如何处理这种情况,因为

struct ItemRaw: Codable {    let parentType: String    enum CodingKeys: String, CodingKey {        case parentType = "type"    }}

抛出"Expected to decode String but found a number instead.",自然,

struct ItemRaw: Codable {    let parentType: Float    enum CodingKeys: String, CodingKey {        case parentType = "type"    }}

相应地抛出"Expected to decode Float but found a string/data instead."

定义我时如何处理这种(和类似的)情况struct

答案1

小编典典

尝试对Reddit列表JSON响应上的“已编辑”字段进行解码/编码时遇到了相同的问题。我创建了一个结构,该结构表示给定键可能存在的动态类型。键可以是布尔值或整数。

{ "edited": false }{ "edited": 123456 }

如果只需要能够解码,则只需实现init(from :)。如果您需要同时使用两种方法,则需要实现encode(to :)函数。

struct Edited: Codable {    let isEdited: Bool    let editedTime: Int    // Where we determine what type the value is    init(from decoder: Decoder) throws {        let container =  try decoder.singleValueContainer()        // Check for a boolean        do {            isEdited = try container.decode(Bool.self)            editedTime = 0        } catch {            // Check for an integer            editedTime = try container.decode(Int.self)            isEdited = true        }    }    // We need to go back to a dynamic type, so based on the data we have stored, encode to the proper type    func encode(to encoder: Encoder) throws {        var container = encoder.singleValueContainer()        try isEdited ? container.encode(editedTime) : container.encode(false)    }}

在我的Codable类中,然后使用我的结构。

struct Listing: Codable {    let edited: Edited}

编辑:针对您的方案的更具体的解决方案

我建议在解码时使用CodingKey协议和一个枚举来存储所有属性。当您创建符合Codable的内容时,编译器将为您创建一个私有枚举CodingKeys。这使您可以根据JSON
Object属性键决定要做什么。

仅举例来说,这就是我正在解码的JSON:

{"type": "1.234"}{"type": 1.234}

如果您只想将double值从字符串转换为Double,则只需解码字符串,然后从中创建一个double。(这是Itai
Ferber所做的,然后您还必须使用trycoder.decode(type:forKey :)对所有属性进行解码)

struct JSONObjectCasted: Codable {    let type: Double?    init(from decoder: Decoder) throws {        // Decode all fields and store them        let container = try decoder.container(keyedBy: CodingKeys.self) // The compiler creates coding keys for each property, so as long as the keys are the same as the property names, we don''t need to define our own enum.        // First check for a Double        do {            type = try container.decode(Double.self, forKey: .type)        } catch {            // The check for a String and then cast it, this will throw if decoding fails            if let typeValue = Double(try container.decode(String.self, forKey: .type)) {                type = typeValue            } else {                // You may want to throw here if you don''t want to default the value(in the case that it you can''t have an optional).                type = nil            }        }        // Perform other decoding for other properties.    }}

如果需要将类型和值一起存储,则可以使用符合Codable的枚举而不是struct。然后,您可以仅使用具有JSONObjectCustomEnum的“
type”属性的switch语句,并根据大小写执行操作。

struct JSONObjectCustomEnum: Codable {    let type: DynamicJSONProperty}// Where I can represent all the types that the JSON property can be. enum DynamicJSONProperty: Codable {    case double(Double)    case string(String)    init(from decoder: Decoder) throws {        let container =  try decoder.singleValueContainer()        // Decode the double        do {            let doubleVal = try container.decode(Double.self)            self = .double(doubleVal)        } catch DecodingError.typeMismatch {            // Decode the string            let stringVal = try container.decode(String.self)            self = .string(stringVal)        }    }    func encode(to encoder: Encoder) throws {        var container = encoder.singleValueContainer()        switch self {        case .double(let value):            try container.encode(value)        case .string(let value):            try container.encode(value)        }    }}

10.4 Swift结构体中的mutating方法

10.4 Swift结构体中的mutating方法

/**

结构体中的mutating方法

值类型(结构体或者枚举)默认方法是不可以修改属性的,也不可以修改self本身

如果要修改需要做特殊处理,函数前加上 mutating

当然在类 class)里面当然是可以修改属性的。

*/

class MyPerson {

var name: String = ""

var age: Int = 0

func set(name: String,age: Int) -> Void {

self.name = name

self.age = age

}

func show() -> Void {

print("name=\(name),age=\(age)")

}

}

var m0 = MyPerson.init()

m0.set(name: "zhangsan",age: 10)

m0.show()

struct MyPerson1 {

var name: String = ""

var age: Int = 0

mutating func set(name: String,age: Int) -> Void {

/**

结构体枚举等值类型的中,这里在普通的实例方法中不允许修改属性

如果一定要修改,在func前面加上 mutating

如果 MyPerson1 class 就没有必要加mutating

*/

self.name = name

self.age = age

}

func show() -> Void {

print("name=\(name),age=\(age)")

}

}


// 这个不可以修改

// let m11 = MyPerson1.init()

// m11.set(name: 1,age: 1)

var m10 = MyPerson1.init()

m10.set(name: "zhangsan",age: 10)

m10.show()

// 枚举里面

enum LightSwitch {

case OFF,LOW,HIGH

// 在枚举中确实可以有成员方法或者实例方法

// 加上 mutating,才可以修改 self

mutating func next() {

switch self {

case .OFF:

self = .LOW

case .LOW:

self = .HIGH

case .HIGH:

self = .OFF


default:

self = .OFF


}

}

}

var light = LightSwitch.OFF

// 调用之后,此时此刻 light == .LOW

light.next()

12.6 Swift结构体的构造方法

12.6 Swift结构体的构造方法

/**

结构体的构造方法

结构体的构造方法和类的构造方法还是有区别的

*/

struct Rect {

var width: Double

var height: Double

// 针对结构体,系统会提供一个结构体成员逐一构造器,所以上面没有初始化值。在类里面没有这个

// init(width: Double,height: Double) {

// self.width = width

// self.height = height

// }

// 如果自定义相应的构造方法,那么系统提供的结构体逐一成员构造器失效

// init() {

// }

}

var r0 = Rect.init(width: 2,height: 1)

// print(r0.width)

// print(r0.height)

5.3 Swift的结构(struct)类型及其下标(subscript) [Swift原创教程]

5.3 Swift的结构(struct)类型及其下标(subscript) [Swift原创教程]

原文:http://coolketang.com/staticCoding/5a9925ac128fe1189bdbd578.html

1. struct结构体是构建代码常用的一种通用灵活的构造体。通过为结构体定义属性和方法,可以扩展结构体的功能。本节课为你演示结构体的使用。



2. 使用struct关键词可以定义一个结构体,结构体的名称通常使用首字母大写的形式。和枚举相同的是,结构体的内容也是放在一对大括号之内。
3. 给结构体定义一个字符串类型的属性,并设置它的默认值为空字符串。
4. 定义一个整型类型的属性,并设置它的默认值为0。
5. 给结构体定义一个方法,用来在控制台输出名称属性的值。
6. 接着实例化一个结构体对象,并设置它的两个属性的值。
7. 调用结构体对象的方法,并查看第11行右侧输出的结果。
8. 当将一个结构体对象赋值给一个变量或常量时,采用的是复制的方式。所以此时animal和animal2两个变量具有不同的内存地址。
9. 你可以尝试修改第二个结构体对象的名称。
10. 然后输出两个结构体对象,并点击底部的显示调试区图标,打开控制台。
11. 从控制台的日志输出可以看出,两个结构体对象具有不同的名称属性。再次点击底部的显示调试区图标,隐藏控制台。
12. 继续编写代码,演示结构体的下标特性。
13. 首先创建一个新的结构体。
14. 给结构体添加一个整型的属性。
15. 然后使用下标关键词,给结构体添加一个下标操作,该下标用来返回当前属性的值的指定倍数。使用下标可以作为访问集合、列表或序列成员元素的快捷方式。
16. 接着初始化一个结构体对象,并设置其属性的值为5。
17. 最后对结构体对象使用下标操作,从右侧的实时反馈区可以看出,最终的结果是当前属性值的两倍。
本文整理自:《Swift4互动教程》,真正的 [手把手]教学模式,用最快的速度上手iOS开发和Swift语言,苹果商店App Store免费下载: https://itunes.apple.com/cn/app/id1320746678 ,或扫描本页底部的二维码。课程配套素材下载地址: 资料下载

8.1 Swift结构体定义

8.1 Swift结构体定义

/**

8.1-结构体定义.mp4

C 中的结构体比较

C 语言中的结构体,不同类型的数据,或者相同类型的数据构成的集合。

不一样的就是Swift语言中的结构体可以拥有方法,甚至是我们后面要讲的构造方法、析构方法

*/

/**

C 语言中我们这样子写结构体

struct Rect {

Double width;

Double height;

}

*/

// swift

struct Rect {

var width: Double

var height: Double

}

今天关于Swift结构:为单个属性处理多种类型swift构造方法的讲解已经结束,谢谢您的阅读,如果想了解更多关于10.4 Swift结构体中的mutating方法、12.6 Swift结构体的构造方法、5.3 Swift的结构(struct)类型及其下标(subscript) [Swift原创教程]、8.1 Swift结构体定义的相关知识,请在本站搜索。

本文标签: