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

水落鱼梁浅,天寒梦泽深<水跃鱼>

可选变量:

一. 在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))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容