Swift-----结构体Struct

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
    }
}
posted @ 2017-03-13 18:46  紫洁  阅读(963)  评论(0编辑  收藏  举报