自定义数据类型 — 结构体(swift)
下面简单的介绍结构体这一自定义数据类型的应用
结构体的基本语法
结构体中构造函数
可失败的构造函数
在结构体和枚举中定义方法
结构体和枚举类型都是值类型
随处都使用的结构体
一:结构体的基础语法
struct Location {//结构体中可以声明属性可以不初始化
let x: Double
let y: Double
}
//这里定义一个结构体变量,定义变量的时候,必须将结构体中的属性进行初始化
var locationApple = Location(x: 234.3, y: 23.3)
locationApple.x
locationApple.y
//同样,结构体类型可以相互套用
struct Place{
let no: Location
let value: Double
}
//这个嵌套的含义在于属性的类型可以使用结构体类型,这个与Class的定义差不多
var myPlace = Place(no: locationApple, value: 1111)
myPlace.no.x
myPlace.no.y
myPlace.value
二:结构体中构造函数
struct Location {
let latitude: Double
let longtitude: Double
init(coordinateString: String){//自定义的构造函数
let currentIndex = coordinateString.rangeOfString(",")!.startIndex
let first = coordinateString.substringToIndex(currentIndex)
let second = coordinateString.substringFromIndex(currentIndex.successor())
latitude = Double(first)!//由于这个字符串不能被转变成double类型,所以,我们用!进行强制类型转换
longtitude = Double(second)!
}
init(latitude: Double, longtitude: Double){
self.latitude = latitude
self.longtitude = longtitude
}
}
let locationApple = Location(coordinateString: "5.3,6.3")
//如果在结构体里面我们自定义了一个init构造函数的话,那么我们将不能使用Location(latitude: 5.3,longtitude: 6.5),如果这样就会报错,那么可以说明,自定义init构造函数的级别高些
//let locationApple = Location(latitude: 5.3,longtitude: 6.5)
//那么为了防止这样的错误,我们最好在结构体中再定义一个init(latitude: 5.3,longtitude: 6.5)函数,那么俩个不论写上哪一个都可以
let locationApple2 = Location(latitude: 4.8, longtitude: 9.8)
三:可失败的结构函数
1.使用 if let 解包
struct Location {
let latitude: Double
let longtitude: Double
init?(coordinateString: String){//如果传入的coordinateString是非法的字符串,就在init后面加上一个问号,表示可以返回一个nil
//并且将所有的可能性进行解包,直到first和second两个值是合法的double类型,再进行赋值,如果不是合法的,那么就返回nil就是
if let currentIndex = coordinateString.rangeOfString(",")?.startIndex{
if let first = Double(coordinateString.substringToIndex(currentIndex)){
if let second =
Double(coordinateString.substringFromIndex(currentIndex.successor())){
latitude = first//由于这个字符串不能被转变成double类型,所以,我们用!进行强制类型转换
longtitude = second
}else{
return nil
}
}else{
return nil
}
}else{
return nil
}
}
init(latitude: Double, longtitude: Double){
self.latitude = latitude
self.longtitude = longtitude
}
}
//如果传入的参数不合法,属性的初始化就会报错
let locationApple = Location(coordinateString: "5.3##,6.3")
let locationApple2 = Location(latitude: 4.8, longtitude: 9.8)
2.使用guard else 进行解包保护
struct Location {
let latitude: Double
let longtitude: Double
init?(coordinateString: String){//如果传入的coordinateString是非法的字符串,就在init后面加上一个问号,表示可以返回一个nil
//使用一个guard将三个let进行解包,如果不满足return nil,满足赋值:latitude = first longtitude = second
guard let currentIndex = coordinateString.rangeOfString(",")?.startIndex,
let first = Double(coordinateString.substringToIndex(currentIndex)),
let second =
Double(coordinateString.substringFromIndex(currentIndex.successor()))
else{
return nil
}
latitude = first
longtitude = second
}
init(latitude: Double, longtitude: Double){
self.latitude = latitude
self.longtitude = longtitude
}
}
//如果传入的参数不合法,属性的初始化就会报错
let locationApple = Location(coordinateString: "5.3##,6.3")
let locationApple2 = Location(latitude: 4.8, longtitude: 9.8)
四:在结构体和枚举中定义方法
struct Location {
let latitude: Double
let longtitude: Double
init?(coordinateString: String){//如果传入的coordinateString是非法的字符串,就在init后面加上一个问号,表示可以返回一个nil
//使用一个guard将三个let进行解包,如果不满足return nil,满足赋值:latitude = first longtitude = second
guard let currentIndex = coordinateString.rangeOfString(",")?.startIndex,
let first = Double(coordinateString.substringToIndex(currentIndex)),
let second =
Double(coordinateString.substringFromIndex(currentIndex.successor()))
else{
return nil
}
latitude = first
longtitude = second
}
init(latitude: Double, longtitude: Double){
self.latitude = latitude
self.longtitude = longtitude
}
//在结构体中和类一样,我们也可以定义方法
func printLocation() {
print("The Location Is My Home")
}
func isNorth() -> Bool {
return self.latitude > 0
}
//而且结构体的方法能调用其他定义在结构体中的方法
func isSouth() -> Bool {
return !self.isNorth()
}
}
//如果传入的参数不合法,属性的初始化就会报错
let locationApple = Location(coordinateString: "5.3##,6.3")
let locationApple2 = Location(latitude: 4.8, longtitude: 9.8)
locationApple2.printLocation()
locationApple2.isNorth()
locationApple2.isSouth()
五:结构体和枚举类型都是值类型
这里就不做代码演示了,结构体和枚举类型都是值类型,其他的基本数据类型也是值类型,但是类的赋值和传递是引用类型
六:随处可见的结构体(所有的基本类型都是结构体)
int double array等等都是结构体类型