iOS基础-- Swift基础知识总结2(可选变量,结构体,类,协议,延展,闭包)

1523603-66a438e81029830a.png
水落鱼梁浅,天寒梦泽深<水跃鱼>

可选变量:

一. 在Swift中可选类型(Optionals),用 " ? " 号表示, 用于处理值缺失的情况. 表示"该处有一个值, 切它等于X", 或者表示"该处没有值"

二. 可选类型是一个包含两种情况的枚举值: None 和 Some , 用来表示可能有值(Some) 或可能没有值(None)
2.1 nil 就是Optional.None, 当你声明一个可选变量, 或者可选属性的时候, 没有提供初始化值, 它的值默认为 nil
2.2 非nil 就是Optional.Some

三. 任何类型都可以明确的声明为可选类型, 当声明一个可选类型的时候, 要确保用括号给" ? " 操作符一个合适的范围. 例如: 声明可选整数数组, 格式为: (Int[])?, 如果写成"Int[]?", 就会报错

定义一个可选类型: 两种方式

var Optional_1:Int? //注意: 在数据类型和" ? "号之间没有空格
var Optional_2:Optional<Int> // 这里表明关键字可选类型

四: " ! " 号, 用来表示强制解析, 如果可选类型实例包含一个值, 可以用" ! "号来访问这个值.
注意: 如果可选类型在没有赋值的情况下, 进行强制解析, 会导致崩溃

var intNumber:Int? = 8
var result1 = intNumber // 打印结果Optional(8)
var result2 = intNumber! // 打印结果直接是 8
print(result1, result2

五. 自动解析(隐式解析)
5.1 你可以在声明可选变量时, 使用 " ! " 号来替换 " ? ", 这样可选变量在使用时, 就不需要在加一个 " ! "进行解析了, 它会自动解析.
5.2 隐式解析可选类型和可选类型一样, 都是有值和没有值(nil)两种结果.
5.3 区别在于赋值/取值时, 隐式解析可选类型不需要再强制解析
5.4 注意: 隐式解析可选类型的变量没有值时, 程序一样会崩溃

var IntNumberOne:Int! = 10
print(IntNumberOne)

六. 可选绑定
6.1 可选绑定: 用来判断, 可选类型是否包含值, 如果包含就把值赋给一个临时常量/临时变量
6.2:可选绑定可以用在 if 和 while 语句中来对可选类型的值进行判断, 并把他赋给一个常量或者变量
6.3 如果你不确定类型是否有值, 用可选绑定, 不需要对可选类型强制解析

var intNumberTow:Int?
if var intNumberThree = intNumberTow
{
    print("可选类型有值 = ",intNumberThree)
}else
{
    print("可选类型没有值")
}```

--------------------
结构体:
-------
>一: 与 C 和 OC 不同的是:
    1.1: 结构体不需要包含实现文件和接口文件
    1.2: 结构体允许我们创建一个单一文件, 且系统会自动生成该结构体面向其他代码的外部接口
 
> 二: 结构体总是通过被复制的方式在代码中传递, 因此, 该结构体原本的值是不可修改的
 
>三: 结构体的应用
    3.1: 在代码中可以使用结构体定义你的自定义类型数据
    3.2:  按照通用的准则, 当符合一条或者多条以下条件时候, 请考虑构建结构体
     >> 3.2.1: 结构体的主要目的是用来封装少量相关简单数据
      3.2.2: 有足够的理由预计一个结构体实例在赋值或者传递时, 封装的数据将会被拷贝而不是应用
      3.2.3: 任何结构体中存储的值类型属性, 也将会被拷贝, 而不是被应用
      3.2.4: 结构体不需要继承另一个已经存在类型的属性或者行为

> 四: 举例:
    4.1: 几何形状大小, 封装一个 width 属性和 height 属性,两者均为 Double 类型
    4.2: 一定范围的路径, 封装一个 Start 属性和 Length 属性, 两者均为 Int 类型
    4.3: 三维坐标系内的一点, X, Y, Z, 三者均为 Double 类型

``` code
// 声明一个结构体
struct piontOf3D
{
    // 声明结构体变量的属性 (存储属性)
    var X : Double
    var Y : Double
    var Z : Double
    
}
// 创建结构体实例
var D3:piontOf3D = piontOf3D.init(X: 1, Y: 1, Z: 1)

// 声明一个结构体
struct Rect
{
    var ponit : (x : Int , y : Int) = (0 , 0)
    var size :(w :Int , h : Int ) = (0 , 0)
// 成员方法
    func getSize()
    {
        print(size)
    }
// 类方法 :  用 Static 修饰
    static func sayHellon ()
    {
        print("你好, 我是结构体类方法")
    }
}
var rect2 : Rect = Rect.init(ponit: (x: 10, y: 10), size: (w: 20, h: 20))
// 调用成员方法
rect2.getSize()
// 调用类方法 (用结构体名调用)
Rect.sayHellon()

类:

一 : swift 中类和结构体有很多共同点
1.1: 定义属性, 用于存储值
1.2: 定义方法, 用于提供功能
1.3: 定义构造器, 用于提供初始化值
1.4: 遵循协议, 用来对某个类提供标准功能
1.5: 通过扩展, 用来增加默认实现的功能

二 : 与结构体 相比又有其他附加功能
2.1: 继承允许一个类继承另一个类的特征
2.2: 类型转换允许在运行时检查和解释一个类实例的类型
2.3: 引用计数: 允许对一个类多次引用

三 : 存储属性: 存储属性就是类或者结构体里定义的变量 (或者变量) (OC 中的一个类中引用另一个类)
3.1: 存储属性可以是变量存储属性(var 修饰), 也可以是常量存储属性(let 修饰)
3.2: 可以在定义存储属性的时候指定默认值
3.3: 也可以在构造过程中设置或者修改存储属性的值

四: 计算属性 不直接存储值, 而是提供一个 getter 和一个可选的 setter, 来间接获取和设置其他属性常量或者变量的值

// 声明一个类
class Car
{
// 声明存储属性
    var kind : String?
// 声明计算属性
    var number : Int
        {
    
        get
        {
            return 10
        }
        set
        {
            print(newValue) // 相当于这个传入参数
        }
    }
    
// 构造方法
    init (kind : String)
    {
        self.kind = kind
    }
}
// 创建实例对象
var volvo = Car (kind: "BMW")
// 访问
print(volvo.kind,volvo.number)
// 声明类属性
class  Docter
{
    // 类属性只能类方法调用
    static var name : String?
    
    // 声明类方法  static 修饰 子类不可以重写  类方法中只能使用类属性 不能使用对象属性
    static func sayBybeBybe ()
    {
        print(name)
    }
    // 子类可以重写的类方法
    class func sayNoByble()
    {
        print(name)
    }
    // 对象方法
    func sayGoodBybe()
    {
        print("我就是实例方法")
    
    }
    
    var age : Int?
    
    var Number : Int{
    
        get
        {
            return age!
        }
        set (value)// 这种写法表示在调用的 Number的 set 方法时, 传过来参数赋给 value
        {
       
            age = value // 切记: set\get 方法中不能使用"self.名称 ", 会造成递归
        
        }
        
    }
    // 构造方法中不能使用类属性
    

}
var DaPeng :  Docter =  Docter()
DaPeng.sayGoodBybe()
// 继承
class nurse: Docter
{
override class func  sayNoByble()
    {
        print("重写了父类的方法, 使用 override 修饰")
    }
}

值类型与引用类型:

一:值类型:
该类型的每一个实例持有数据的副本, 并且该副本对于每一个实例来说都是唯一的一份, 比如结构体, 枚举, 元组都是值类类型

二: 值类型使用场景
2.1: 当使用"==" 运算符比较实例数据的时候
2.2: 当想单独赋值一份实例数据的时候
2.3: 在多线程环境下操作数据的时候

三: 引用类型(如同 OC 中的指针指向同一内存)
该类型的实例共享数据唯一的一份副本, 比如说(class)类就是引用类型

值类型:

struct StructObject
{
    var data : Int = 1
}
var value_1 : StructObject = StructObject()

// 将 value_1 的值赋给 value2, 就是一个拷贝的过程
var value_2 = value_1
print(value_2)
// 这里只能改变 value_1  的值 不能改变 value_2 的值  这些都是值类型
value_1.data = 0
print("值引用都是副本\(value_1.data)************\(value_2.data)")

引用类型:

class ClassObjecct
{
    var data : Int = -1
    
}
var cob_1 = ClassObjecct()
// 将 cob_1的值赋给 cob_2, 就是引用的过程
var cob_2 = cob_1
cob_1.data = 4
print("引用类型, 改一个全部改了",cob_1.data, cob_2.data)
var  cob_3 = ClassObjecct()
print(cob_3.data)


协议:

  • 1: 协议定义了一个蓝图,规定了用来实现某一特定工作或者功能所必需的方法和属性
  • 2: 类, 结构体, 枚举都可以遵守协议, 并提供具体实现来完成协议定义的方法和功能
  • 3: 任意能够满足协议要求的类型, 被称为(conform)这个协议
  • 4: 使用"@objc"修饰的协议, 其中的方法, 可以声明成可选实现(用 optional 修饰)
注意1:
  • 使用@objc修饰的协议表示 OC 的协议
  • @objc修饰的协议不可用在结构体里面遵守
  • 使用@objc修饰的协议里可以声明可选实现的函数(用optional修饰函数)
  • 在实现这个函数的时候,在函数前面要加@objc修饰
注意2:
  • 使用mutating修饰的函数可以在结构体里面修改结构体的属性
  • 协议里面使用mutating修饰的函数,在遵守协议的时候可以不使用mutating修饰,在类里没有影响,在结构体力面,就不能修改属性的值了.
  • 但是如果实现协议里没有mutating修饰的函数的时候,却用了mutating修饰,结果是在结构体重新声明了一个函数,此函数和协议无关系

// 带有可选实现函数的协议

@objc protocol MenDelegate
{
    func cook()
    func wash()
    optional func hitJJ()
}

// 必须实现的 函数协议

protocol DividDelegate
{
    func lookKid()
 }```
- 要遵循某个协议, 如果类在遵循协议的同时拥有父类, 应该将父类名放在协议之前, 用逗号隔开

```code
# doc 继承于 Docter类 遵守 MenDelegate,DividDelegate协议
class doc: Docter,MenDelegate,DividDelegate
{
#实现协议方法
    @objc func cook() {
        print("做饭的女人")
    }
    @objc func wash() {
        print("洗衣服的女人")
    }   
     func lookKid() {
        print("照顾孩子")
    }
}
// 创建实例 并调用类的实例方法
var doc1 : doc = doc()
doc1.cook()
doc1.lookKid()
doc1.wash()

延展:

1: Extension + 类名或者结构体名 (可以给一个类或者结构体扩展方法)
2: Extension 可以多次对一个类进行扩展, 也可以给一个类扩展协议方法
3: 扩展就是向一个已有的类, 结构体, 枚举添加新功能
4: 扩展可以对一个类型添加新的功能, 但是不能重写已有的方法

// 给 doc 类扩展方法
extension doc
{
// 实例方法
    func say()
    {
        print("i-LOVE-u")
    }
// 扩展类方法
    class func eat()
    {
        print("i-WANT-u")
    }

}
doc.eat()
doc1.say()

// 扩展一个 类 遵循协议中的方法
@objc protocol Magic
{
   func magic ()
}
extension doc : Magic
{
    @objc func magic()
    {
        print("我会变魔术")
    }
}
var docc : doc = doc()
docc.magic()

// 给协议新添加方法并实现  遵循这个协议的实例可以调用这个方法
// 扩展一个 类遵循协议  中的方法
extension MenDelegate
{
     func magic()
    {
       print("12345678")
    }
    
}
class stu : MenDelegate
{
    @objc func wash() {
        
    }
    @objc func cook() {
        
    }

}

var sutt : stu = stu()
sutt.magic()


闭包:

1: 闭包: 是自包含的函数代码块, 可以再代码中被传递, 使用
2: Swift 中的闭包和 OC 中的 Block 以及其他语言中的匿名函数类似
3: 闭包可以捕获和存储其所在上下文中任意的常量和变量 (闭包并包裹着这些常量和变量)
4: Swift 会帮你管理在捕获过程中涉及到的内存操作
5: 格式: {(参数名 : 类型) ->返回值类型 in 需要执行的代码 }
6: let backString = {(name : String) -> String in return name }
7: 闭包的函数体部分由关键字 in 引入, 该关键字表示闭包的参数和返回值类型定义已经完成, 闭包函数体即将开始

代码举例:

// 求两个数的最大值
               // (a : Int , b : Int ) -> Int是表示maxReult的函数类型
var maxReult : ((a : Int , b : Int ) -> Int )
// 第一种方式
maxReult = {(a : Int , b : Int ) -> Int in
    return a > b ? a : b
}

// 第二种方式
maxReult = { a , b -> Int in return a > b ? a : b }

// 第三种方式
maxReult = { a , b in a > b ? a : b }

// 第四种方式  (官方推荐)
maxReult = {( a , b) -> Int in return a > b ? a : b }
// 第五种方式
maxReult = {  $0 > $1 ? $0 : $1   }

print(maxReult(a: 3,b: 5))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值