//可选类型(?)其根源是一个枚举类型,里面有None和Some两种类型,所谓的nil就是Optional.None, 非nil就是Optional.Some
//如果可选类型(?)沒值,再强制解包的话,就会崩溃
var intNumber:Int? =8
print(intNumber)
//使用 !强制解包
print(intNumber!)
//可选绑定
if var num =intNumber {
print(num)
}
//隐式解析可选类型(!):有值,沒值(nil)
//注意:如果沒值,再使用的话就会崩溃
var intNum:Int! =23
print(intNum)
//可选绑定
if var intNM =intNum {
print(intNM)
}
//*************** 结构体(struct)和 类(class) *****************************************
/*
类和结构体
1, 定义类的关键字为class,结构体的关键字是struct
2, 类和结构体中没有实例变量的概念,都是属性
3, 无论类中还是结构体中,都要遵循一个构造方法安全性原则:必须保证初始化出来的对象的每个属性都必须有初始值
为了遵循这个原则,我么可以在声明属性时,用以下三种方案:
方案一,声明的时候,给每个属性赋初值.
方案二,定制(自定义)构造方法,在构造方法中完成所有属性的赋值
方案三,选择可选类型,这是最优解(系统也是这样做)
*/
//结构体
//1, 声明结构体
struct Rect {
//声明结构体变量的属性(存储属性)
var x:Float =0
var y:Float =0
var width:Float =0
var height:Float =0
//声明结构体属性 ---需要用static 关键字修饰
staticvar des:String?
//计算属性 ---通过setter 或者 getter方法,可以用于计算其他属性的值,并不存储值
var centerX:Float {
//setter
set (newValue) { //这种写法表示调用centerX的setter 方法时,传过来的参数值是 newValue
x = newValue -width / 2
}
//如果setter和 getter 同时存在 ,代表该计算属性可读可写;如果只有getter方法,代表了该计算属性只读
//getter
get { //可以省去get关键字
returnx + width /2
}
}
//方法
//声明结构体变量方法
func allInfo() {
print("x =\(x), y =\(y), width =\(width), height =\(height)")
}
//声明结构体方法 ---方法前用 static 修饰
staticfunc sayHello() {
print("")
}
}
//1, 根据结构体类型(Rect),用结构体自带的构造方法创建结构体对象(结构体变量)
var rect = Rect(x:10, y: 10, width:50, height: 50)
//注意:如果结构体对象用let修饰(常量),内部的属性是不允许修改的
//2, 结构体属性的访问
//访问结构体对象属性
rect.y =20
print(rect.y)
//访问结构体属性
Rect.des = "sgasdg"
print(Rect.des)
//可选绑定
if var description =Rect.des {
print(description)
}
//3, 结构体方法的使用
//结构体对象方法
rect.allInfo()
//结构体方法
Rect.sayHello()
//************************ 类 (class) ********************************************
class Person {
//声明对象属性(存储属性) ---将来存储一个值
var name:String?
var age:Int?
//声明类属性
staticvar des:String?
//计算属性 :本身没有值,通过setter and getter方法进行赋值 或者取值操作
var number:Int {
get {
returnage!
}
set {
//注意:setter and getter 中不能使用self.属性 ,会造成递归
age = newValue
}
}
//声明计算属性类型的类属性
staticvar carType:String {
return"辉昂"
}
//声明类方法:使用static和class 都可以修饰类方法,区别在于, class修饰的类方法,可以被子类重写
staticfunc sayHi() {
print("")
}
classfunc sayByebye() {
print("")
}
//对象方法
func sayHello() {
print("")
}
//声明构造方法(初始化方法)
init(name:String, age:Int) {
self.name = name
self.age = age
}
}
//创建对象
var person = Person(name:"xiluo", age: 19)
//属性的使用
person.age =18 //对象属性
Person.des = "这是一个"//类属性
//方法的使用
person.sayHello() //对象方法
Person.sayByebye() //类方法
//拓展
class coolPerson {
//Swift 中的懒加载属性
//只有在使用到的时候,才会开辟空间,懒加载属性必须有初值
lazyvar height:Float =1
//属性观察器
var age:Int =30 {
//在大括号中,对age进行观察
//值将要变化
willSet {
print("newValue =\(newValue)")
}
//值已经改变
didSet {
print("oldValue =\(oldValue)")
}
}
}
//创建对象
var coolPer = coolPerson()
//验证属性观察器
coolPer.age =13
//继承**************
class Student:Person {
//重写父类的方法,在方法前面加 override
overrideclass func sayByebye() {
print("重写了sayByebye")
}
}
var stu = Student(name:"xiapming", age: 11)
Student.sayByebye()
//********************** 值类型,引用类型
//***************** 值类型,引用类型
// 一,值类型
// eg. 结构体
struct anminal {
var name:String?
var age:Int?
}
var dog = anminal(name:"大黄", age:2)
var dog1 = dog// 此时, dog1是从 dog 拷贝过来的值,在一块新的空间上
dog.name ="小花"
print("dog =\(dog.name!), dog1 =\(dog1.name!)")
// 引用类型
// 类
class anminalClass {
var name:String?
var age:Int?
// 构造方法
init(name:String, age:Int) {
self.name = name
self.age = age
}
}
var classDog = anminalClass(name:"大黄", age:3)
var classDog1 = classDog// 此时, 将 classDog 的值赋给 classDog1,只是引用的过程
classDog.name ="小花"
print("classDog =\(classDog.name!), classDog1 =\(classDog1.name!)")
//*********************** 协议(protocol)
//当协议中有可选实现的方法时,该协议前要用关键字@objc 修饰,可选的方法前用optional 修饰
@objc protocol MarryDelegate {
func cooking()
func cleanHouse()
optionalfunc giveBirthTo()
}
class Man: Person,MarryDelegate {
@objcfunc cooking() {
print("心动吗")
}
@objcfunc cleanHouse() {
print("了")
}
}
//**********************************Extension (扩展)
//1, 扩充一个类遵循的协议中的方法
extension Man {
@objcfunc giveBirthTo() {
print("gjlkj")
}
}
//2, 扩展类的方法(给一个类扩充方法)
extension Man {
//扩展对象方法
func sing() {
print("")
}
//扩展类方法
classfunc playGame() {
print("")
}
}
//************** 闭包
//闭包是自包含的函数代码块,可以在代码中被传递和使用,Swift中的闭包与 C 语言和Object C中的代码块(block)以及其他编程语言中的匿名函数比较相似
//求两个数最大值
//func maxValue(a:Int, b:Int) -> Int
// 该函数类型 (a:Int, b:Int) -> Int
var maxResult:((a:Int, b:Int) ->Int)
// 第一种方式,闭包实现
maxResult = {
(a:Int, b:Int) ->Int in
return a > b ? a : b
}
// 第二种方式,闭包实现
maxResult = {
(a, b) in
return a > b ? a : b
}
// 第三种方式,闭包实现
maxResult = {
(a, b) -> Intin
return a > b ? a : b
}
// 第四种方式,闭包实现
maxResult = {
a, b in
a > b ? a : b
}
// 第五种方式,闭包实现
maxResult = {
$0 > $1 ? $0 : $1
}
// 调用
print(maxResult(a:3, b: 5))