十. 可选类型
1.可选类型的介绍
- 注意:
- 可选类型时swift中非常难理解的一个知识点
- 暂时先了解,多利用Xcode的提示来使用
- 随着学习的深入,慢慢理解其中的原理和好处
- 概念:
- 在OC开发中,如果一个变量暂停不使用,可以赋值为0(基本属性类型)或者赋值为空(对象类型)
- 在swift开发中,nil也是一个特殊的类型.因为和真实的类型不匹配是不能赋值的(swift是强语言)
- 但是开发中赋值nil,在所难免.因此推出了可选类型
- 可选类型的取值:
- 空值
- 有值
2.定义可选类型
- 定义一个可选类型有两种写法
- 最基本的写法
- 语法糖(常用)
// 错误写法 // let string : String = nil // 正确写法: // 写法一:定义可选类型 let string : Optional<String> = nil // 写法二:定义可选类型,语法糖(常用) let string : String? = nil
3.可选类型的使用
// 演练一: // 定义可选类型 var string : Optional<String> = nil // 给可选类型赋值 string = "Hello world" // 打印结果 print(string) // 结果:Optional("Hello world")n // 因为打印出来的是可选类型,所有会带Optional // 演练二: // 取出可选类型的真实值(解包) print(string!) // 结果:Hello worldn // 注意:如果可选类型为nil,强制取出其中的值(解包),会出错 string = nil print(string!) // 报错 // 正确写法: if string != nil print(string!) } // 简单写法:为了让在if语句中可以方便使用string if var str = string print(str) }
4.真实应用场景
- 目的:让代码更加严谨
// 通过该方法创建的URL,可能有值,也可能没有值 // 错误写法:如果返回值是nil时,就不能接收了 let url : NSURL = NSURL(string: "www.x.com") // 正确写法:使用可选类型来接收 let url : NSURL? = NSURL(string: "www.x.com") // 通过url来创建request对象 if let tempUrl = url let request = NSURLRequest(URL: tempUrl) }
十一. 函数
1.函数的介绍
- 函数相当于OC中的方法
- 函数的格式如下
func 函数名(参数列表) -> 返回值类型 代码块 return 返回值 }
- func是关键字,多个参数列表之间可以用逗号(,)分隔,也可以没有参数
- 使用箭头“->”指向返回值类型
- 如果函数没有返回值,返回值为Void.并且“-> 返回值类型”部分可以省略
2.常见的函数类型
// 1.没有参数,没用返回值 func about() -> Void print("iphone6s plus") } // 调用函数 about() // 简单写法 // 如果没用返回值,Void可以写成() func about1() -> () print("iphone6s plus") } // 如果没有返回值,后面的内容可以都不写 func about2() print("iphone6s plus") } about2() // 2.有参数,没用返回值 func callPhone(phoneNum : String) print("打电话给(phoneNum)") } callPhone("+86 11011") // 3.没用参数,有返回值 func readMessage() -> String return "吃饭了吗?" } var str = readMessage() print(str) // 4.有参数,有返回值 func sum(num1 : Int, num2 : Int) -> Int return num1 + num2 } var result = sum(20, num2: 30) print(result)
3.函数的使用注意
- 注意一: 外部参数和内部参数
- 在函数内部可以看到的参数,就是内部参数
- 在函数外面可以看到的参数,就是外部参数
- 默认情况下,从第二个参数开始,参数名称既是内部参数也是外部参数
- 如果第一个参数也想要有外部参数,可以设置标签:在变量名前加标签即可
- 如果不想要外部参数,可以在参数名称前加
// num1和a是外部参数的名称 func ride(num1 num1 : Int, a num2 : Int, b num3 : Int) -> Int return num1 num2 num3 } var result1 = ride(num1: 20, a: 4, b: 5) // 方法的重载:方法名称相同,但是参数不同,可以称之为方法的重载(了解) func ride(num1: Int, num2 :Int) -> Int return num1 num2 } var result2 = ride(20, 20)
- 注意二: 默认参数
- 某些情况,如果没有传入具体的参数,可以使用默认参数
func makecoffee(type :String = "卡布奇诺") -> String return "制作一杯(type)咖啡。" } let coffee1 = makecoffee("拿铁") let coffee2 = makecoffee()
- 注意三: 可变参数
- swift中函数的参数个数可以变化,它可以接受不确定数量的输入类型参数
- 它们必须具有相同的类型
- 我们可以通过在参数类型名后面加入(...)的方式来指示这是可变参数
func sum(numbers:Double...) -> Double var total: Double = 0 for number in numbers total += number } return total } sum(100.0, 20, 30) sum(30, 80)
- 注意四: 引用类型(指针的传递)
- 默认情况下,函数的参数是值传递.如果想改变外面的变量,则需要传递变量的地址
- 必须是变量,因为需要在内部改变其值
- Swift提供的inout关键字就可以实现
- 对比下列两个函数
// 函数一:值传递 func swap(var a : Int, var b : Int) let temp = a; a = b; b = temp print("a:(a), b:(b)") } var a = 10 var b = 20 swap(a, b: b) print("a:(a), b:(b)") // 函数二:指针的传递 func swap1(inout a : Int, inout b : Int) let temp = a a = b b = temp print("a:(a), b:(b)") } swap1(&a, b: &b) print("a:(a), b:(b)")
- 函数的嵌套使用
- swift中函数可以嵌套使用
- 即函数中包含函数,但是不推荐该写法
// 函数的嵌套 let value = 55 func test() func demo() print("demo (value)") } print("test") demo() } demo() // 错误 test()
十二. Swift中类的定义
1.类的介绍
- Swift也是一门面向对象开发的语言
- 面向对象的基础是类,类产生了对象
- 在Swift中如何定义类呢?
- class是Swift中的关键字,用于定义类
class 类名 : SuperClass // 定义属性和方法 }
- 注意:
- 定义的类,可以没有父类.那么该类是rootClass
- 通常情况下,定义类时.继承自NSObject(非OC的NSObject)
2.如何定义类的属性
类的属性介绍
- Swift中类的属性有多种
- 存储属性:存储实例的常量和变量
- 计算属性:通过某种方式计算出来的属性
- 类属性:与整个类自身相关的属性
- 存储属性
- 存储属性是最简单的属性,它作为类实例的一部分,用于存储常量和变量
- 可以给存储属性提供一个默认值,也可以在初始化方法中对其进行初始化
- 下面是存储属性的写法
- age和name都是存储属性,用来记录该学生的年龄和姓名
- chineseScore和mathScore也是存储属性,用来记录该学生的语文分数和数学分数
class Student : NSObject // 定义属性 // 存储属性 var age : Int = 0 var name : String? var chineseScore : Double = 0.0 var mathScore : Double = 0.0 } // 创建学生对象 let stu = Student() // 给存储属性赋值 stu.age = 10 stu.name = "ryan" stu.chineseScore = 89.0 stu.mathScore = 98.0
- 计算属性
- 计算属性并不存储实际的值,而是提供一个getter和一个可选的setter来间接获取和设置其它属性
- 存储属性一般只提供getter方法
- 如果只提供getter,而不提供setter,则该计算属性为只读属性,并且可以省略get
- 下面是计算属性的写法
- averageScore是计算属性,通过chineseScore和mathScore计算而来的属性
- 在setter方法中有一个newValue变量,是系统指定分配的
class Student : NSObject // 定义属性 // 存储属性 var age : Int = 0 var name : String? var chineseScore : Double = 0.0 var mathScore : Double = 0.0 // 计算属性 var averageScore : Double get return (chineseScore + mathScore) / 2 } // 没有意义.newValue是系统分配的变量名,内部存储着新值 set self.averageScore = newValue } } } // 获取计算属性的值 print(stu.averageScore)
- 类属性
- 类属性是与类相关联的,而不是与类的实例相关联
- 所有的类和实例都共有一份类属性.因此在某一处修改之后,该类属性就会被修改
- 类属性的设置和修改,需要通过类来完成
- 下面是类属性的写法
- 类属性使用static来修饰
- courseCount是类属性,用来记录学生有多少门课程
class Student : NSObject // 定义属性 // 存储属性 var age : Int = 0 var name : String? var chineseScore : Double = 0.0 var mathScore : Double = 0.0 // 计算属性 var averageScore : Double get return (chineseScore + mathScore) / 2 } // 没有意义.newValue是系统分配的变量名,内部存储着新值 set self.averageScore = newValue } } // 类属性 static var corseCount : Int = 0 } // 设置类属性的值 Student.corseCount = 3 // 取出类属性的值 print(Student.corseCount)
- 监听属性的改变
- 在OC中我们可以重写set方法来监听属性的改变
- Swift中可以通过属性观察者来监听和响应属性值的变化
- 通常是监听存储属性和类属性的改变.(对于计算属性,我们不需要定义属性观察者,因为我们可以在计算属性的setter中直接观察并响应这种值的变化)
- 我们通过设置以下观察方法来定义观察者
- willSet:在属性值被存储之前设置。此时新属性值作为一个常量参数被传入。该参数名默认为newValue,我们可以自己定义该参数名
- didSet:在新属性值被存储后立即调用。与willSet相同,此时传入的是属性的旧值,默认参数名为oldValue
- willSet与didSet只有在属性第一次被设置时才会调用,在初始化时,不会去调用这些监听方法
- 监听的方式如下:
- 监听age和name的变化
class Person : NSObject var name : String? // 可以给newValue自定义名称 willSet (new) // 属性即将改变,还未改变时会调用的方法 // 在该方法中有一个默认的系统属性newValue,用于存储新值 print(name) print(new) } // 可以给oldValue自定义名称 didSet (old) // 属性值已经改变了,会调用的方法 // 在该方法中有一个默认的系统属性oldValue,用于存储旧值 print(name) print(old) } } var age : Int = 0 var height : Double = 0.0 } let p : Person = Person() // 在赋值时,监听该属性的改变 // 在OC中是通过重写set方法 // 在swift中,可以给属性添加监听器 p.name = "ryan" //p.name = "szy"
时间: 2024-08-05 19:41:03