01-enumeration
//: Playground - noun: a place where people can play
importUIKit
varstr ="Hello, playground"
/*目录:
* 1. why?
*/
/*如果没有枚举类型,描述四个方向
north = "1" / south = "2" / east = "3" / west = "4"
*/
vardirection ="sourth"
/*枚举类型场景:将有限个可能性封装在一个类型中
*使用Swift语言的枚举描述一周信息
*
*/
//简单写法
enumWeekTwo {
caseMonday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
enumWeek {
caseMonday// monday可以接受
caseTuesday
caseWednesday
caseThursday
caseFriday
caseSaturday
caseSunday
}
//把枚举类型作为函数传参
funcworkDay(week:Week) ->String{
// switch语句
switchweek {
case.Monday, .Tuesday, .Wednesday, .Thursday, .Friday:
return"This is the working day!"
case.Saturday, .Sunday:
return"This is the weekend!"
}
}
//把枚举类型赋值给变量
varcurrentDay =Week.Friday
currentDay= .Saturday//类型就是Week
workDay(currentDay)
//特殊:将每种可能性和整型数值绑定
// raw data:声明枚举类型的时候,给定一个原始数值/数据(原始)
enumWeekWithInt:Int{
caseMonday =1// 0
caseTuesday =2// 1
caseWednesday =3
caseThursday =4
caseFriday =5
caseSaturday =6
caseSunday =7
}
varweek =WeekWithInt.Friday
//调用WeekWithInt枚举类型的构造函数方式
ifletweekTwo =WeekWithInt(rawValue:4) {
print("The current day is\(weekTwo)")
}
enumCoin:Int{
casePenny=1
caseNikel=5
caseDime=10
caseQuarter =25
}
//枚举还可以绑定其它的类型String
enumDevice:String{
caseiPod="iPod"
caseiPhone="iPhone"
caseiPad="iPad"
casemacBook ="macBook"
}
//需求:将枚举中的可能性和某个类型绑定,给定动态的值
// associated value:将枚举类型中的某个/某些可能性和类型绑定
enumATMStatus {
//取钱成功之后,还剩余多少钱
caseSuccess(Int)
caseError(String)
caseWaiting
}
//卡里有多少钱
varbalance =1000
//函数:给定要取得钱数(Int),返回是枚举类型ATMStatus
funcwithDraw(amount:Int) ->ATMStatus{
//可以取钱
ifbalance>= amount {
balance-= amount
return.Success(balance)
}else{
return.Error("Not enough money")
}
}
letleftMoney =withDraw(200)
/*课堂练习1:
* 1.声明描述月份Month的枚举类型(12月)
* 2.声明函数,参数月份的枚举类型,返回属于哪个季节(季节枚举;或者只返回季节的字符串)
* 3.调用函数,查看返回是否正确
*/
enumMonth:Int{
caseJanuary =1
caseFebruary =2
caseMarch =3
caseApril =4
caseMay =5
caseJUN =6
caseJUL =7
caseAUG =8
caseSeptember =9
caseOctober =10
caseNovember =11
caseDecember =12
}
enumSeason {
caseSpring
caseSummer
caseAutumn
caseWinter
}
funccurrentSeason(month:Month) ->Season{
switchmonth{
case.January, .February, .March:
return.Spring
case.April, .May, .JUN:
return.Summer
case.JUL, .AUG, .September:
return.Autumn
case.October, .November, .December:
return.Winter
}
}
letnow =currentSeason(.JUL)
/*课堂练习2:
* 1.给定描述形状Shape的枚举类型;可能性包含:正方形Square/长方形Rectangle/圆形Circle/点Point
* 2.每个可能性case分别绑定不同的元组
* 3.case Square(side: Double); Rectangle绑定两个分量;Circle绑定三个元组分量; Point不绑定
* 4.声明函数;传参是Shape枚举,返回该形状的面积值Double
* 5.调用验证
*/
enumShape {
caseSquare(side:Double)
caseRectangle(width:Double, height:Double)
caseCircel(centerX:Double, centerY:Double, radius:Double)
casePoint
}
funcarea(shape:Shape) ->Double{
switchshape {
caselet.Square(side):
returnside * side
caselet.Rectangle(width, height):
returnwidth * height
caselet.Circel(_,_, radius):
returnM_PI* radius * radius
case.Point:
return0
}
}
//声明四个枚举类型常量
letsquare =Shape.Square(side:10)
letrectangle =Shape.Rectangle(width:10, height:20)
letcicle =Shape.Circel(centerX:0, centerY:0, radius:5)
letpoint =Shape.Point
area(square)
area(rectangle)
area(cicle)
area(point)
//了解:枚举类型中,添加自定义函数
enumShapeWithFunc {
caseSquare(side:Double)
caseRectangle(width:Double, height:Double)
caseCircel(centerX:Double, centerY:Double, radius:Double)
casePoint
funcarea() ->Double{
switchself{
caselet.Square(side):
returnside * side
caselet.Rectangle(width, height):
returnwidth * height
caselet.Circel(_,_, radius):
returnM_PI* radius * radius
case.Point:
return0
}
}
}
//声明枚举;调用area
letsquareTwo =ShapeWithFunc.Square(side:20)
squareTwo.area()
//从枚举角度重新认识可选型
//显示声明一个整型可选型
varimInt:Optional =20
varage:Int? =18
print("\(age)")
//可选型的完整声明
//enum Optional {
//case None //nil
//case Some(T)
//}
//最完整的声明字符串可选型的方式:
varimString:Optional =Optional.Some("hello")
//简单形式一:
varimStringTwo:Optional ="hello"
//简单形式二(推荐):
vargreetingStr:String? ="hello"
switchgreetingStr{
case.None:
print("No Greeting")
caselet.Some(greeting):
print("greeting is\(greeting)")
}
// if let解包(简单形式一)
ifletgreetingStr =greetingStr{
print("greeting is\(greetingStr)")
}else{
print("No Greeting")
}
//简单形式二
letnewString =greetingStr??"No Greeting"
02-structure
//: Playground - noun: a place where people can play
importUIKit
varstr ="Hello, playground"
/*声明和创建
* 1.关键词struct
*/
varstring =String()
varimInt=Int()
varimIntValue =Int(10)
/*结构体场景:需要使用多个属性一起描述该事物
*/
//需求:描述用户所在地图的位置(经纬度两个属性)
structLocation {
letlatitude:Double
letlongitude:Double
//默认编译器自动创建构造函数(init),包含了所有的属性的初始化;按照声明属性的先后顺序进行初始化的
}
//创建结构体常量/变量
varappleLocation =Location(latitude:37.3230, longitude: -122.0322)
letgoogleLocation =Location(latitude:37.4220, longitude: -122.0841)
//如何获取结构体中的属性的值
appleLocation.latitude
googleLocation.longitude
//赋值
appleLocation=googleLocation
appleLocation.latitude
//结构体嵌套
structPlace {
letlocation:Location
varname:String
}
//创建Place结构体变量
vargooglePlace =Place(location:googleLocation, name:"Google Int.")
googlePlace.name
03-structure-init
//: Playground - noun: a place where people can play
importUIKit
varstr ="Hello, playground"
/* 1.init没有返回类型
* 2.如果添加了自定义的构造函数,之前默认的包含所有属性的构造函数就失效
*/
//自定义的构造函数
structLocation {
letlatitude:Double
letlongitude:Double
//初始化经纬度的方式: 39.1234,116.4567字符串
init(coordinateString:String) {
// 1.找到逗号所在的索引
letcommaIndex = coordinateString.rangeOfString(",")!.startIndex
// 2.subStringFrom/To...
letfirstElement =Double(coordinateString.substringToIndex(commaIndex))!
letsecondElement =Double(coordinateString.substringFromIndex(commaIndex.successor()))!
// 3.将取出的经纬度赋值两个属性
latitude= firstElement
longitude= secondElement
}
//手动添加原来的默认构造函数
init(latitude:Double, longitude:Double) {
self.latitude= latitude
self.longitude= longitude
}
//手动添加没有参数的构造函数
init() {
self.latitude=0.0
self.longitude=0.0
}
//例外:构造函数不需要对可选型进行初始化
varplaceName:String?
//建议有一个包含所有属性初始化的构造函数(包括可选型);当然可以没有
init(latitude:Double, longitude:Double, placeName:String) {
self.latitude= latitude
self.longitude= longitude
self.placeName= placeName
}
}
varimInt =Int()
//创建Location结构体常量
letbeijingLocation =Location(coordinateString:"39.123,116.456")
beijingLocation.latitude
beijingLocation.longitude
//调用原来的默认的构造函数
letlocationWithInit =Location(latitude:39.124, longitude:116.6789)
//调用没有传参的构造函数
varlocationWithoutParam =Location()
locationWithoutParam.longitude
locationWithoutParam.placeName="Beijing"
04-refactor
//: Playground - noun: a place where people can play
importUIKit
varstr ="Hello, playground"
/* 1.init没有返回类型
* 2.如果添加了自定义的构造函数,之前默认的包含所有属性的构造函数就失效
*/
//自定义的构造函数
structLocation {
letlatitude:Double
letlongitude:Double
//初始化经纬度的方式: 39.1234,116.4567字符串
//优化
/*1.语法:对应的方法/属性后面添加?->可选型的解包
*2.optional chaining:可选型的链式解包
*3.init?:可失败的构造函数(无法对结构体中的属性进行初始化) -> Failable Initializer
*/
init?(coordinateString:String) {
ifletcommaIndex = coordinateString.rangeOfString(",")?.startIndex{
ifletfirstElement =Double(coordinateString.substringToIndex(commaIndex)) {
ifletsecondElement =Double(coordinateString.substringFromIndex(commaIndex.successor())) {
latitude= firstElement
longitude= secondElement
}else{
returnnil
}
}else{
returnnil
}
}else{
returnnil
}
}
//手动添加原来的默认构造函数
init(latitude:Double, longitude:Double) {
self.latitude= latitude
self.longitude= longitude
}
//手动添加没有参数的构造函数
init() {
self.latitude=0.0
self.longitude=0.0
}
//例外:构造函数不需要对可选型进行初始化
varplaceName:String?
//建议有一个包含所有属性初始化的构造函数(包括可选型);当然可以没有
init(latitude:Double, longitude:Double, placeName:String) {
self.latitude= latitude
self.longitude= longitude
self.placeName= placeName
}
}
varimInt =Int()
//创建Location结构体常量
letbeijingLocation =Location(coordinateString:"hello#116.456")
//beijingLocation.latitude
//beijingLocation.longitude
//调用原来的默认的构造函数
letlocationWithInit =Location(latitude:39.124, longitude:116.6789)
//调用没有传参的构造函数
varlocationWithoutParam =Location()
locationWithoutParam.longitude
locationWithoutParam.placeName="Beijing"
//某个函数的返回类型
varerrorMessage:String? =nil//"Not Found"
letmessage =errorMessage??"No Error"
//可选型的链式解包
errorMessage?.uppercaseString
/* guard语句:保卫某个条件是否满足
* if条件{} else {}
*语法:guard条件else {}
*/
//自定义函数:四个参数Int,给定已有钱数、商品价格、背包容量、商品的容量
funcbuySomething(money:Int, price:Int, capacity:Int, volume:Int) {
ifmoney >= price {
ifcapacity >= volume {
print("I can buy it!")
}else{
print("Not enough capacity!")
}
}else{
print("Not enough money!")
}
}
funcbuy(money:Int, price:Int, capacity:Int, volume:Int) {
//增强可读性
guardmoney >= priceelse{
print("Not enough money!")
return
}
guardcapacity >= volumeelse{
print("Not enough capacity!")
return
}
//.....
print("You can buy it")
}
05-guard
//: Playground - noun: a place where people can play
importUIKit
varstr ="Hello, playground"
/* 1.init没有返回类型
* 2.如果添加了自定义的构造函数,之前默认的包含所有属性的构造函数就失效
*/
//自定义的构造函数
structLocation {
letlatitude:Double
letlongitude:Double
init?(coordinateString:String) {
//guard let commaIndex = coordinateString.rangeOfString(",")?.startIndex else {
//return nil
//}
//guard let firstElement = Double(coordinateString.substringToIndex(commaIndex)) else {
//return nil
//}
//guard let secondElement = Double(coordinateString.substringFromIndex(commaIndex.successor())) else {
//return nil
//}
//latitude= firstElement
//longitude = secondElement
//版本二:只使用一个guard语句
guardletcommaIndex = coordinateString.rangeOfString(",")?.startIndex,
letfirstElement =Double(coordinateString.substringToIndex(commaIndex)),
letsecondElement =Double(coordinateString.substringFromIndex(commaIndex.successor()))else{
returnnil
}
latitude= firstElement
longitude= secondElement
}
init(latitude:Double, longitude:Double) {
self.latitude= latitude
self.longitude= longitude
}
//手动添加没有参数的构造函数
init() {
self.latitude=0.0
self.longitude=0.0
}
//例外:构造函数不需要对可选型进行初始化
varplaceName:String?
//建议有一个包含所有属性初始化的构造函数(包括可选型);当然可以没有
init(latitude:Double, longitude:Double, placeName:String) {
self.latitude= latitude
self.longitude= longitude
self.placeName= placeName
}
//自定义的函数
funcprintLocation() {
print("latitude is\(latitude) and longitude is\(longitude)")
}
//自定义的函数,调用另一个自定义的函数
funcisNorth() ->Bool{
returnself.latitude>0
}
funcisSouth() ->Bool{
return!self.isNorth()
}
}
varimInt =Int()
//创建Location结构体常量
letbeijingLocation =Location(coordinateString:"hello#116.456")
ifletlatitude =beijingLocation{
latitude.latitude
}else{
print("Error")
}
//调用原来的默认的构造函数
letlocationWithInit =Location(latitude:39.124, longitude:116.6789)
//调用没有传参的构造函数
varlocationWithoutParam =Location()
locationWithoutParam.longitude
locationWithoutParam.placeName="Beijing"
//前面讲的所有的结构体的语法都适用于类
//结构体特殊语法: mutating在class中不需要;原因:类是引用类型(reference type)
structPoint {
varx:Int=0
vary:Int=0
//自定义方法: mutating关键词的作用,要用自定义的方法修改结构体中的属性值
mutatingfuncgoEast() {
x+=1
}
}
//编译器默认提供的构造函数
//var point = Point(x: 10, y: 10)
//已经给两个属性初始值
varpoinTwo =Point()
poinTwo.x
poinTwo.goEast()
poinTwo.x
///////////--------guard语法-----------//////////
//某个函数的返回类型
varerrorMessage:String? =nil//"Not Found"
letmessage =errorMessage??"No Error"
//可选型的链式解包
errorMessage?.uppercaseString
/* guard语句:保卫某个条件是否满足
* if条件{} else {}
*语法:guard条件else {}
*/
//自定义函数:四个参数Int,给定已有钱数、商品价格、背包容量、商品的容量
funcbuySomething(money:Int, price:Int, capacity:Int, volume:Int) {
ifmoney >= price {
ifcapacity >= volume {
print("I can buy it!")
}else{
print("Not enough capacity!")
}
}else{
print("Not enough money!")
}
}
funcbuy(money:Int, price:Int, capacity:Int, volume:Int) {
//增强可读性
guardmoney >= priceelse{
print("Not enough money!")
return
}
guardcapacity >= volumeelse{
print("Not enough capacity!")
return
}
//.....
print("You can buy it")
}
06-funtion-type.
//: Playground - noun: a place where people can play
importUIKit
varstr ="Hello, playground"
/*需求:如何将函数赋值给一个变量/常量
*/
funcmultipy(numberOne:Int,_numberTwo:Int) ->Int{
returnnumberOne * numberTwo
}
//语法:将函数的名字赋值给一个常量
letmultipyConstant =multipy
letmultipyConstantTwo: (Int,Int) ->Int=multipy
multipy(10,20)
multipyConstant(10,20)
//随机产生包含30个元素的整型数组
vararray: [Int] = []
for_in0..<30{
array.append(random()%30)
}
//默认从小到大排序
array.sort()
// array.sort(isOrderedBefore: (Int, Int) -> Bool)
//array.sort(<#T##isOrderedBefore: (Int, Int) -> Bool##(Int, Int) -> Bool#>)
//倒序:自定义的排序方法(Int, Int) -> Bool
funcgetBiggerNumber(firstNumber:Int, secondNumber:Int) ->Bool{
returnfirstNumber > secondNumber
}
//距离20近的在前面
funcnear20(firstNumber:Int, secondNumber:Int) ->Bool{
returnabs(firstNumber-20)
}
array.sort(getBiggerNumber)
array.sort(near20)
array
/*需求:给学生打分;
*打分原则1:对分数开平方*10: 36分->60分
*打分原则2:对分数/150*100
*打分原则3:每个人加+5分
*/
//改分的接口
funcchangeScores(inoutscores: [Int], by changeScore: (Int) ->Int) {
for(index, score)inscores.enumerate() {
scores[index] = changeScore(score)
}
}
//打分原则1:对分数开平方*10: 36分->60分
funcchangeScoreOne(score:Int) ->Int{
returnInt(sqrt(Double(score)) *10)
}
//打分原则2:对分数/150*100
funcchangeScoreTwo(score:Int) ->Int{
returnInt(Double(score) /150.0*100.0)
}
//打分原则3:每个人加+5分
funcchangeScoreThree(score:Int) ->Int{
returnscore +5
}
varscoresOne = [36,61,78,56]
changeScores(&scoresOne, by:changeScoreOne)
scoresOne
Day03总结
1. 值类型(value type): Int/Float/Double/String/Dictionary/Array/Set/enum/struct
2.编译器上面所有的类型都当成值;值的拷贝copy(副本)
3. 操作:赋值; 传参
新内容:
枚举类型
1. 为什么需要枚举类型?
2. Swift语言中枚举特殊
3.样例:如何创建枚举,如何使用枚举类型?
[ 01-enumeration ]
枚举角度再看可选型
结构体: 在Swift普遍程度高
1. 和类的不同:结构体没有继承的;类可以继承
2.样例:如何声明结构体;创建结构体
[ 02-structure ]
1.样例:添加自定义的构造函数(初始化函数): 为结构体的属性进行初始化
[ 03-structure-init ]
2.样例:优化03(三个强制解包)
[ 04-refactor ]
案例(练习)
1.功能:随机产生0~100的整数,在UITextFiled上输入猜测的值;
2.要求:
a. 必须使用枚举类型;
b. 及时的更新最上面的Label
c. 当用户猜对的时候,尝试添加UIAlertController,包含一个UIAlertAction;需要显示猜测的次数
函数类型的变量/常量
1. 将函数直接赋值给变量/常量, 目的可以作为其他函数的参数
2. 样例:将函数直接赋值给变量/常量, 变量/常量称为“函数类型的变量/常量”
[ 06-funtion-type ]
Day03知识点:
—> 枚举相关
1.场景:将有限个可能性封装在一个结构中
2.语法:使用enum关键词声明,使用case来列举有限个可能性
3.raw value:将枚举类型中的每个case和一个固定的值绑定,该值一旦绑定,不可修改
4.associated value:将枚举类型中的每个case和某个类型绑定,极大扩展了枚举类型的灵活性
—> 结构体相关
1.场景:使用多个属性或者方法描述某个事物/对象
2.语法:使用struct关键词;
3.功能:可以添加属性;可以添加自定义构造函数/方法;可以添加自定义的方法
4.备注:
a. 如果对结构体的属性都赋初始值,此时编译器会默认添加没有参数的构造函数;同时会默认添加包含所有属性初始值的构造函数
struct Location {
var latitude = 0.0
var longitude = 0.0
}
// 创建
var location = Location()
var newLocation = Location(latitude: 35.33, longitude: 37.33)
b. 如果添加了自定义的构造函数,上面的默认构造函数会失效,需要手动添加(详细样例,请查看03-structure-init.playground文件)
c. 如果添加的自定义方法,需要修改结构体中属性的值,此时需要添加mutating关键词; 此语法不适用类class
-> guard语句相关:
1.语法:如果不满足条件(无法守护),执行else大括号逻辑;否则,继续执行大括号外的逻辑
guard条件else{}
2.使用场景:如果if语句的嵌套会导致语义的不清晰,可以考虑使用guard语句;
3. 详细样例可查看05-guard.playground文件
-> 函数类型的变量/常量
1.语法:可以将函数赋值给某个变量或者常量;目的可以作为另一个函数的参数;此时的变量或者常量称为函数类型的常量或者变量
2. 详细样例可查看06-funtion-type文件