Swift5.0 - day2-流程控制、函数、枚举(上)

简介: Swift5.0 - day2-流程控制、函数、枚举(上)

一、流程控制



  • 1.1、if 语句


let age = 5
if age > 10  {
    print("\(age) 大于 10 ")
} else if  age > 3 {
    print("\(age) 大于 3 ")
} else {
    print("\(age) 小于 3 ")
}


提示:

  • if 后面的条件可以省略小括号,而条件后面的花括号不可以省略
  • if 后面的类型只能是 bool 类型


image.png


  • 1.2、while 语句(先判断后执行)


var num = 5
while num > 0 {
     num -= 1
     print("num=\(num)")
}
  • 打印结果:num=4、num=3、num=2、num=1、num=0
  • 1.3、repeat while 语句(先执行后判断)


var num = -1
repeat{
    print("num=\(num)")
}while num > 0
  • 打印结果:num=-1,


提示:repeat-while 相当于 OC 里面的 do-while


  • 1.4、for 语句
  • 闭区间运算符:a...ba<= 取值 <=b


let names = ["小1","小2","小3","小4"]
for i in 0...3 {
     print("name=\(names[i])")
}

提示:上面的 0...3 可以替换为 let range = 0...3


let a =  0
var b = 3
let names = ["小1","小2","小3","小4"]
for i in a...b {
    print("name=\(names[i])")
}

提示:区间可以用常量或者变量来表示的


for _ in 0...3 {
    print("😆")
}

打印了 四次 😆

  • for 循环里面的 i 默认是 let,有需要的时候我们可以声明为 var,如下


for var i in 1...3 {
    i += 2
    print("i=\(i)")
}
  • 打印结果:3、4、5
  • 半开区间运算符:a..<ba <= 取值 < b


for i in 1..<3 {
   print("i=\(i)")
}
  • 打印结果:1、2
  • 1.5、for - 区间运算符用在数组上
  • 例一


let names = ["小1","小2","小3","小4"]
for name in names[0...3] {
     print("name=\(name)")
}
  • 打印结果:小1、小2、小3、小4
  • 例二:单侧区间:让区间朝一个方向尽可能的远


let names = ["小1","小2","小3","小4"]
for name in names[1...] {
    print("name=\(name)")
}
  • 打印结果:小2、小3、小4


let names = ["小1","小2","小3","小4"]
for name in names[...2] {
    print("name=\(name)")
}
  • 打印结果:小1、小2、小3


let names = ["小1","小2","小3","小4"]
for name in names[..<2] {
    print("name=\(name)")
}
  • 打印结果:小1、小2


let range = ...5
print(range.contains(8))
print(range.contains(3))
print(range.contains(-1))
  • 打印结果:false、true、true

提示: let range = ...5 代表 range的范围从无穷小到 5,包含5

  • 1.6、区间类型(重点)


let range1:ClosedRange<Int> = 1...3
let range2:Range<Int> = 1..<3
let range3:PartialRangeThrough<Int> = ...5
  • 字符、字符串也能进行区间运算,但默认不能在 for-in 中,因为 ClosedRange:不可数的闭区间


let stringRange1 = "cc"..."ff" // ClosedRange<String>
stringRange1.contains("cb")   // false
stringRange1.contains("dz")   // true 
stringRange1.contains("fg")   // false
let stringRange2 = "a"..."f"  // ClosedRange<String>
stringRange2.contains("d")    // true
stringRange2.contains("n")    // false


提示:比较的是ascii,第1位比较第1位,第2位比较第2位,如果第1位大于第1位就没必要比较第二位了,依次类推



image.png

image.png

  • 0到~包含了所有可能要用到的 ASCII 字符


let characterRange:ClosedRange<Character> = "\0"..."~"
characterRange.contains("b")   // true
  • 1.8、带间隔的区间值


let hours = 12
let hourInterval = 2
// 从tickMark 的取值:从 4 开始,累加2,不超过 12
for tickMark in stride(from: 4, to: hours, by: hourInterval) {
    print("tickMark=\(tickMark)")
}
  • 打印结果:4、6、8、10
  • 1.9、switch 语句
  • 案例一:switch的基本使用


var num = 10
switch num {
case 1:
     print("值是1")
     break
case 2:
     print("值是2")
     break
case 3:
     print("值是3")
     break
default:
     print("没有匹配")
     break
}

提示:case 和 default 后面不能写大括号 {},默认可以不写 break,并不会贯穿到后面的条件


  • 案例二:使用 fallthrough 可以实现贯穿效果


var num = 1
switch num {
case 1:
   print("num 值是 1")
   fallthrough
case 2:
   print("num 值是 2")
case 3:
   print("num 值是 3")
default:
   print("没有匹配")
}
  • 打印结果:num 值是 1、num 值是 2
  • switch使用注意点:
  • <1>、switch 必须能保证处理所有的情况


image.png

  • <2>、case 或者 default 后面至少有一条语句,如果不想有语句可以写 break


var num = 1
switch num {
case 1:
    print("num 值是 1")
case 2:
    break
default:
    print("没有匹配")
}
  • <3>、如果能保证处理所有的情况,也可以不必使用 default,如下


enum Answer {case right,wrong}
let answer = Answer.right
switch answer {
case Answer.right:
    print("right")
case Answer.wrong:
    print("wrong")
}

提示:上面已经确定 answer 是 Answer 类型,因此可以省略 Answer

enum Answer {case right,wrong}
let answer = Answer.right
switch answer {
case .right:
     print("right")
case .wrong:
     print("wrong")
}
  • 复合条件:switch也支持Character、String 类型,如下例子
  • 例一:String 类型


let name = "marry"
switch name {
case "Jack":
    print("Jack")
case "marry":
    print("marry")
default:
    print("找不到某人")
}
  • 例二:String 类型


let name = "marry"
switch name {
case "Jack","marry":
    print("Jack and marry")
default:
    print("找不到某人")
}
  • 例三:Character 类型


let character = "A"
switch character {
case "a","A":
    print("字母 a或者A")
default:
    print("找不到字母")
}
  • 匹配区间和元组匹配
  • 匹配区间


let count = 20
switch count {
case 0:
   print("none")
case 1..<5:
   print("a few")
case 5..<100:
   print("several")
case 100..<1000:
   print("hundreds of")
default:
   print("many")
}
  • 元组匹配


let point = (1,1)
switch point {
case (0,0):
   print("the origin")
case (_,0):
   print("on the x-axis")
case (0,_):
   print("on the y-axis")
case (-2...2,-2...2):
   print("inside the box")
default:
   print("many")
}

提示:可以使用 _ 忽略某个值

  • 值绑定:必要时,let 可以改为 var


let point = (2,0)
switch point {
case (let x,0):
   print("on the x-axis with an x value of \(x)")
case (0,let y):
   print("on the y-axis with an y value of \(y)")
case let (x,y):
   print("somehere else at (\(x),\(y))")
}
  • 1.10、where语句


let point = (2,-2)
switch point {
case let (x,y) where x == y:
    print("on the line x == y")
case let (x,y) where x == -y:
    print("on the line x == -y")
case let (x,y):
    print("(\(x),\(y)) is just some arbitrary point")
}
  • 例二:所有的正数相加


let numbers = [-1,2,3,-10,20]
var sum = 0
for num in numbers where num > 0 {
   sum += num
}
print("最后正数的和=\(sum)")

提示:where 用来过滤 负数

  • 1.11、标签语句


outer: for i in 1...4{
   for k in 1...4 {
      if k == 3 {
          continue outer
      }
      if i == 3 {
          break outer
      }
      print("i=\(i) k=\(k)")
   }
}


二、函数



  • 2.1、函数的定义:是一组代码的组合,因此函数也被称为完成特殊功能的代码块。函数三要素:函数名、参数、返回值。
  • 有返回值,有参数


func pi()->Double{
    return 3.14
}
print(pi())
func sum(num1:Int,num2:Int)->Int{
    return num1 + num2
}
print(sum(num1: 1, num2: 3))

提示:形参默认是 let,也只能是 let

  • 无返回值,无参数;下面的几种 无返回值表达的意思是一样的


func sayHello()->Void{
   print("Hello")
}
func sayHello()->(){
   print("Hello")
}
func sayHello(){
   print("Hello")
}
  • 2.2、函数的隐式返回


func sum(num1:Int,num2:Int) -> Int{
     num1 + num2
}
sum(num1: 1, num2: 3)

提示:如果整个函数的整体是一个单一的表达式,那么函数会隐式返回这个表达式

  • 2.3、返回元组 和 实现多值返回


func calculate(v1: Int,v2:Int) -> (sum:Int,difference:Int,average:Int){
     let sum = v1 + v2
     return (sum,v1-v2,sum>>1)
}
let result = calculate(v1: 20, v2: 10)
result.sum   // 和 
result.difference  // 差 : 10
result.average   // 二进制右移 是 平均值 15

提示:sum>>1 代表值的二进制数 右移 求平均值


/// 求和 【概述】
///
/// 将两个整数相加 【更详细的描述】
///
/// - Parameter v1: 第 1 个整数
/// - Parameter v2: 第 2 个整数
/// - Returns : 两个整数的和
///
/// - Note:传入两个整数即可 【批注】,有没有什么特殊的用法
///
func sum(_ v1:Int,_ v2:Int) -> Int{
    return v1 + v2
}
sum(10, 20)


  • 效果如下:


image.png


  • 2.5、参数标签
  • 可以修改参数标签


func goToWork(at time:String){
     print("this time is \(time)")
}
goToWork(at: "08:00")
  • 打印结果:this time is 08:00
  • 可以使用下划线 _ 省略参数标签


func sum(_ v1:Int,_ v2:Int) -> Int{
    return v1 + v2
}
sum(10, 20)
  • 2.6、默认参数值(Default Parameter Value)
  • 参数可以有默认值


func check(name:String = "noPerson",age:Int,job:String = "iOS"){
    print("名字=\(name) 年龄=\(age) 工作=\(job)")
}
check(name: "老大", age: 19, job: "iOS")
check(name: "老二", age: 19)
check(age: 10, job: "前端")
check(age: 16)

提示:只要是有默认参数值的就可以不传参数

  • C++的默认参数值有个限制:必须从右往左设置。由于Swift拥有参数标签,因此并没有此类限制
  • 但是在省略参数标签时,需要特别注意,避免出错,如下
    这里的 two 不可以省略参数标签


func test(_ one:Int = 10,two:Int,_ three:Int = 20){
    print("打印 one = \(one) two = \(two) three = \(three)")
}
test(two: 9)


  • 2.7、可变参数(Variadic Parameter)


func sum(_ numbers: Int...) -> Int {
   var total = 0
   for i in numbers {
       total += I
   }
   return total
}
sum(1,2,3)

提示:一个函数 最多只能有1个 可变参数;紧跟在可变参数后面的参数不能省略参数标签,如下


func test(_ numbers:Int...,string:String,_ other:String){
}
test(1,2,3, string: "iOS", "Rose")

参数 string 标签不能省略

  • 2.8、Swift 自带的 print 函数


/// - Parameters:
///   - items: Zero or more items to print.
///   - separator: A string to print between each item. The default is a single
///     space (`" "`).
///   - terminator: The string to print after all items have been printed. The
///     default is a newline (`"\n"`).
public func print(_ items: Any..., separator: String = " ", terminator: String = "\n")
  • 分析: 第一个参数是要打印的值,第二个参数是:连接第一个参数值的 字符,第三个参数是:默认是 \n 换行,如下例子
print(1,2,3,4,5)
print(1,2,3, separator: "_")
print(1,2,3, separator: "_", terminator: "")
print("哈哈")
  • 打印结果是: 最后一行不换行,因为 "\n" 被用  "" 取代了


1 2 3 4 5
1_2_3
1_2_3哈哈
  • 2.9、输入输出参数 (In-Out Parameter)
    可以用 inout 定义一个输入输出函数:可以在函数内部修改外部实参的值


func swapValues(_ v1:inout Int,_ v2:inout Int){
    let tem = v1
    v1 = v2
    v2 = tem
}
var num1 = 10
var num2 = 20
swapValues(&num1, &num2)
print(num1,num2)
  • 打印结果:20 10
  • 提示:下面的函数与上面的等价:传进去的是 内存地址,所以可以修改其外部参数的值


func swapValues(_ v1:inout Int,_ v2:inout Int){
   (v1,v2) = (v2,v1)
}
  • 可变参数不能标记为 inout
  • 输入输出参数不能有默认值
  • 输入输出参数不能传入常量(let)、字面量作为实参。也就是可以被多次赋值的 变量
  • inout 参数的本质是地址传递 (引用传递)


  • 2.10、函数重载 (Function Overload)
    规则:函数名相同
    参数个数不同 || 参数类型不同 || 参数标签不同


func sum(v1:Int,v2:Int) -> Int{
   return v1 + v2
}
  • 参数个数不同


func sum(v1:Int,v2:Int,v3:Int) -> Int{
    return v1 + v2
}
  • 参数类型不同


func sum(v1:Int,v2:Double) -> Double{
   return Double(v1) + v2
}
func sum(v1:Double,v2:Int) -> Double{
   return v1 + Double(v2)
}
  • 参数标签不同


func sum(_ v1:Int,_ v2:Int) -> Int{
   return v1 + v2
}
func sum(a:Int,b:Int) -> Int{
   return a + b
}
  • 函数重载注意点一: 返回值类型 与 函数重载 无关


func sum(a:Int,b:Int) -> Int{
    return a + b
}
func sum(a:Int,b:Int) {
}
sum(a: 1, b: 2)
  • 函数重载注意点二:默认参数值和函数重载一起使用产生二义性时,编译器并不会报错(在 C++ 中会报错)


func sum(a:Int,b:Int) -> Int {
     return a + b
}
func sum(a:Int,b:Int,c:Int = 10) -> Int {
    return a + b + c
}
// 会调用 sum(a:Int,b:Int),这样不太好,还不如编译器报错
sum(a: 1, b: 2)
  • 函数重载注意点三:可变参数,省略参数标签,函数重载一起使用产生二义性时,编译器有可能会报错


func sum(a:Int,b:Int) -> Int{
    return a + b
}
func sum(_ a:Int,_ b:Int) -> Int {
    return a + b
}
func sum(_ numbers: Int...)->Int{
    var total = 0
    for i in numbers {
        total += I
    }
    return total
}


  • 调用 sum(1,2) 报错:Ambiguous use of 'sum'
目录
相关文章
|
1月前
|
存储 定位技术 Swift
Swift 中的枚举与结构体,包括它们的定义、特性、使用场景及示例
本文深入探讨了 Swift 中的枚举与结构体,包括它们的定义、特性、使用场景及示例。枚举适合表示有限的、离散的状态或选项,结构体则适用于具有特定属性和行为的数据结构。两者在存储方式、继承性和灵活性上有所不同,但在实际开发中常结合使用,以充分发挥各自优势。
41 3
|
1月前
|
设计模式 安全 测试技术
Swift代码审查的关键点及最佳实践,涵盖代码风格一致性、变量使用合理性、函数设计、错误处理、性能优化、安全性、代码注释等方面,旨在提升代码质量和项目管理水平
本文深入探讨了Swift代码审查的关键点及最佳实践,涵盖代码风格一致性、变量使用合理性、函数设计、错误处理、性能优化、安全性、代码注释等方面,旨在提升代码质量和项目管理水平。通过实际案例分析,展示了如何有效应用这些原则,确保代码的高可读性、可维护性和可靠性。
30 2
|
1月前
|
安全 编译器 Swift
Swift 函数
10月更文挑战第27天
17 1
|
1月前
|
Swift iOS开发
Swift 枚举
10月更文挑战第28天
27 0
|
5月前
|
Swift iOS开发 Kotlin
苹果iOS新手开发之Swift中实现类似Kotlin的作用域函数
Swift可通过扩展实现类似Kotlin作用域函数效果。如自定义`let`, `run`, `with`, `apply`, `also`,增强代码可读性和简洁性。虽无直接内置支持,但利用Swift特性可达成相似功能。
78 7
|
6月前
|
Swift C++ 索引
Swift开发——简单函数实例
函数是编程的基础,用于封装特定功能的代码。它们有关键词func、函数名、参数列表(可为空)和返回类型。多返回值可通过元组、数组、inout参数或可选类型实现。例如,返回元组 `(value1, value2)`,数组 `[value1, value2]` 或使用可选数组 `[[Double]]?`。函数可以作为其他函数的参数,类似闭包或Lambda表达式。在Swift中,示例展示了通过元组、带索引的元组、数组和可选类型返回多个值的函数。还演示了如何使用inout参数交换变量值。
121 5
Swift开发——简单函数实例
|
7月前
Swift4.0判断本函数是否在其它类有相同的方法
Swift4.0判断本函数是否在其它类有相同的方法
46 0
|
7月前
|
存储 API Swift
【Swift开发专栏】Swift函数与闭包的实战应用
【4月更文挑战第30天】本文介绍了 Swift 中函数和闭包的实战应用。首先,函数的基本使用包括定义、参数与返回值、函数类型以及高级技巧如嵌套函数。接着,讨论了闭包的语法,包括无名函数、作为函数参数、简写形式和尾随闭包。最后,展示了函数和闭包在实战中的应用,如排序过滤集合和处理异步任务的回调。
54 0
|
7月前
|
存储 定位技术 Swift
【Swift 开发专栏】Swift 中的枚举与结构体
【4月更文挑战第30天】本文探讨了Swift中的枚举与结构体,包括它们的定义、用法及差异。枚举用于表示有限状态或选项,如游戏状态;结构体适合表示具有特定属性和行为的数据,如商品信息。两者均可定义属性和方法,作为函数参数。枚举以整数存储,不可继承,结构体按属性存储且可继承,更灵活。理解两者特点有助于提升编程效率。
40 0
|
7月前
|
存储 Swift
Swift 语言:什么是闭包(Closure)?它们与函数的区别是什么?
Swift 语言:什么是闭包(Closure)?它们与函数的区别是什么?
156 1