1 结构体的构造函数
(1)如果结构体中不写初始化函数,则默认会有一个设置全部参数的构造函数。
注意:初始化函数中的参数顺序应该跟结构体定义中的参数顺序相同。
struct Location { let latitude: Double let longitude: Double } // 如果结构体中不写初始化函数,默认会有一个设置全部参数的构造函数 let appleHeadLocation = Location(latitude: 32.3730, longitude: -122.0322)
(2)如果在结构体的构造中,变量设置了默认值。怎结构体会有两个初始化函数,一个是:没有任何参数的函数;一个是含有全部参数的函数。但是初始化函数中不能只为部分变量赋值。要不全部都赋值、要不都不要赋值。
struct Location { var latitude: Double = 0 var longitude: Double = 0 } let appleHeadLocation1 = Location() let appleHeadLocation2 = Location(latitude: 32.3730, longitude: -122.0322) // 注意:如果在声明结构体的时候,有默认值。则可以通过以上两种方式来初始化对象,但是不能像下面这样只为其中的一个变量赋值。要不就全部赋值,要不就一个都不需要赋值 //let appleHeadLocation3 = Location(latitude: 32.3730)
(3)如果结构体中定义了初始化方法,则系统默认的含有全部参数的初始化方法将不能在使用
struct Location { let latitude: Double let longitude: Double // 参数格式为: 23.89,89.67 init(coordinateString: String) { let commaIndex: Range<String.Index>? = coordinateString.range(of: ",") let beforeIndex = coordinateString.index(commaIndex!.upperBound, offsetBy: -1) let firstElement = coordinateString.substring(to: beforeIndex) let afterIndex = coordinateString.index(commaIndex!.upperBound, offsetBy: 1) let secondElement = coordinateString.substring(from: afterIndex) latitude = Double(firstElement) ?? 0 longitude = Double(secondElement) ?? 0 } } let appleHeadLocation1 = Location(coordinateString: "32.3730,-122.0322") // 如果结构体中定义了初始化方法,则系统默认的含有全部参数的初始化方法将不能在使用 //let appleHeadLocation2 = Location(latitude: 32.3730, longitude: -122.0322)
(4)如果仍需要用到含有全部参数的初始化方法,则需要在结构体中重新定义该方法
struct Location { let latitude: Double let longitude: Double // 23.89,89.67 init(coordinateString: String) { let commaIndex: Range<String.Index>? = coordinateString.range(of: ",") let beforeIndex = coordinateString.index(commaIndex!.upperBound, offsetBy: -1) let firstElement = coordinateString.substring(to: beforeIndex) let afterIndex = coordinateString.index(commaIndex!.upperBound, offsetBy: 1) let secondElement = coordinateString.substring(from: afterIndex) latitude = Double(firstElement) ?? 0 longitude = Double(secondElement) ?? 0 } init(latitude: Double, longitude: Double) { self.latitude = latitude self.longitude = longitude } } let appleHeadLocation1 = Location(coordinateString: "32.3730,-122.0322") let appleHeadLocation2 = Location(latitude: 32.3730, longitude: -122.0322)
2 使用failable-initializer(在init后面加‘?’)
init?(coordinateString: String) { // 注意:通过guard let定义的变量,在之后的代码中是可以使用的;但是通过if let定义的变量在之后的代码中不可以使用 guard let commaIndex = coordinateString.range(of: ",") else { return nil } let beforeIndex = coordinateString.index(commaIndex.upperBound, offsetBy: -1) let afterIndex = coordinateString.index(commaIndex.upperBound, offsetBy: 1) guard let firstElement = Double(coordinateString.substring(to: beforeIndex)), let secondElement = Double(coordinateString.substring(from: afterIndex)) else { return nil } latitude = firstElement longitude = secondElement }
3 结构体是值类型, 赋值相等于是copy
在Swift中,Array、Dictionary、Set都是结构体,故它们都是值类型.
Int、Float、Double、Bool、String都是结构体。
let a: Array<Int> = [1, 2, 3] var b = a // 将a copy一份给b b.append(4) b // {1, 2, 3, 4} a // {1, 2, 3} let m: Dictionary<String, String> = ["name": "Tom", "age": "20"] var n = m n["name"] = "Lily" n // {"name": "Lily", "age": "20"} m // {"name": "Tom", "age": "20"} let s:Set<Int> = [1, 2, 3] var t = s t.insert(4) t // {2, 3, 1, 4} s // {2, 3, 1}
4 如果要在一个结构体的方法中改变自身的值,需要在方法前面添加mutating关键字
struct Location { var latitude: Double var longitude: Double mutating func changeLatitude() { self.latitude = 10 } }