美文网首页
Swift5.0 小马哥_02流程控制、函数

Swift5.0 小马哥_02流程控制、函数

作者: MR_詹 | 来源:发表于2020-12-26 14:08 被阅读0次

    if else

    • if后面的条件可以省略小括号
    • 条件后的大括号不可以省略
    • if后面的条件只能是bool类型
    let age = 4
    if age >= 22 {
      print("Get married")
    }else if age >= 18 {
      print("Being a adult")
    }else if age >=7 {
      print("Go to school")
    } else {
      print("Just a child")
    }
    

    while

    var num = 5
    while num > 0 {
      print("num is \(num)")
      num -= 1
    }  /// 打印5次
    

    repeat - while(相当于C语言中的do-while)

    var num = -1 
    repeart {
      print("num is \(num)")
    } while num > 0  /// 打印一次
    

    for

    闭区间运算符:a...b , a <= 取值 <= b

    let names = ["Anna","Alex","Brian","Jack"]
    for i in 0...3 {
      print(names[I])
    }
    
    /// i默认是常量 let,有需要时可以声明var
    for var i in 1...3 {
      i += 5
      print(i)
    }  /// 打印结果:6 7 8 
    
    
    let range = 1...3
    for i in range {
      print(names[I])
    }
    
    
    let a = 1
    let b = 2
    for i in a...b {
      print(names[I])
    }
    
    for i in a...3 {
      print(i)
    }
    
    
    /// 如果序号不需要使用,可以用下划线(_)代替
    for _ in 1...3 {
      print("for")
    }  /// 打印3次
    

    半开区间运算符:a..<b ,a <= 取值 < b

    for i in 1..<5 {
      print(i)
    } /// 打印结果 1 2 3 4
    

    for - 区间运算符用在数组上

    let names = ["Anna","Alex","Brian","Jack"]
    for name in names[0...3] {
      print(name)
    }  /// 打印结果:Anna,Alex,Brian,Jack
    

    单侧区间:让区间朝一个方向尽可能的远

    for name in names[2...] {
      print(name)
    }  /// 打印结果:Brian,Jack
    
    
    for name in names[...2] {
      print(name)
    }  /// 打印结果:Anna,Alex,Brian
    
    
    for name in names[..<2] {
      print(name)
    }  /// 打印结果:Anna,Alex
    
    
    /// 表示:负无穷到5的范围区间
    let range = ...5
    range.contains(7)  /// false
    range.contains(4)  /// true
    range.contains(-3)  /// true
    

    where 条件筛选

    /// 将所有正数相加
    var numbers = [10,20,-10,-20,30,-30]
    var sum = 0
    for num in numbers where num > 0 {
      sum += num
    }
    print(sum)
    

    区间类型

    let range1 : ClosedRange<Int> = 1...3
    let range2 : Range<Int> = 1..<3
    let range3 : PartialRangeThrough<Int>= ...5
    

    字符、字符串也能使用区间运算符,但默认不能使用for-in中

    let stringRange1 = "cc"..."ff"
    stringRange1.contains("cb")  /// false
    stringRange1.contains("dz")  /// true
    stringRange1.contains("fg")  /// false
    
    let stringRange2 = "a"..."f"
    stringRange2.contains("d")  /// true
    stringRange2.contains("h")  /// false
    
    /// \0 到 ~ 囊括了所有可能要用到的ASCII字符
    let characterRange:ClosedRange<Character> = "\0"..."~"
    characterRange.contains("G")  /// true
    

    带间隔的区间值

    let hours = 11
    let hourInterval = 2
    /// from: 从哪个数开始
    /// through :  到哪个数结束
    /// by : 间隔多少
    for tickMark in stride(from:4,through:hours,by:hourInterval) {
      print(tickMark)
    }  /// 打印结果:4 6 8 10
    

    switch

    • case、default 后面不能写大括号{}
    • switch 默认可以不写break,并不会贯穿到后面的条件
    var number = 1
    switch number {
      case 1 : 
        print("number is 1")
      case 2: 
        print("number is 2")
      default:
        print("number is other")
    }
    

    fallthrough 可以实现贯穿效果(只会贯穿到下一个条件)

    var number = 1
    switch number {
      case 1 : 
        print("number is 1")  
        fallthrough
      case 2: 
        print("number is 2")
      case 3: 
        print("number is 3")
      default:
        print("number is other")
    }
    /// 打印结果:
    ///  number is 1
    ///  number is 2
    

    注意点:switch必须要保证能处理所有情况

    /// 这种情况会报错,因为number除了1和2 还有其他的情况未处理
    var number = 1
    switch number {
      case 1: 
        print("number is 1")
      case 2:
        print("number is 2")
    }
    

    case、default 后面至少要有一条语句
    如果不想做任何事,加个break即可

    var number = 1
    switch number {
      case 1:
        print("number is 1")
      case 2:
        print("number is 2")
      default:
         break
    }
    

    switch 也支持Character、String类型

    let string = “Jack”
    switch string {
      case "Jack":
        print("Jack")
      case "Rose":
        print("Rose")
      default:
        break
    }
    

    复合条件

    let string = “Jack”
    switch string {
      case "Jack","Rose":
        print("Right person")
      default:
        break
    }
    

    区间匹配、元组匹配

    let count = 62 
    switch count {
      case 0:
         print("none")
      case 1..<5: 
        print("a few")
      case 5..<12:
        print("several")
      case 12..<100:
        print("dozens of")
      case 100..<1000:
        print("hundreds of")
      default:
        print("many")
    }  /// 打印结果:dozens of
    
    /// 可以使用下划线(_) 忽略某个值
    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("outside of the box")
    }  /// 打印结果:inside the box
    

    值绑定

    /// 必要时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("somewhere else at (\(x),\(y))")
    }
    

    where

    let point = (1,-1)
    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")
    }
    

    标签语句

    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)")
      }
    }
    

    函数

    函数的定义

    /// func :函数的前缀
    /// pi  : 函数名
    /// Double : 函数返回值的类型
    func pi() -> Double {
      return 3.14  
    }
    
    /// v1,v2都是函数的形参
    /// 形参默认是let,也只能是let
    func sum(v1:Int , v2: Int) -> Int {
      return v1 + v2
    }
    /// 函数调用
    sum(v1:10,v2:20)
    

    无返回值

    /// 以下三种写法都是等价的
    
    
    func sayHello() -> Void {
      print("Hello")
    }
    
    func sayHello -> () {
       print("Hello") 
    }
    
    /// 这种写法比较常用
    func sayHello {
      print("Hello")
    }
    

    隐式返回

    /// 如果整个函数是一个单一表达式,那么函数会隐式返回这个表达式
    
    fun sum(v1: Int , v2: Int) -> Int {
      v1 + v2
    }
    sum(v1:10,v2:20)
    

    返回元组: 实现多返回值

    func calcuate (v1: Int, v2: Int) -> (sum: Int, difference: Int , average: Int) {
      let sum = v1 + v2
      returen (sum,  v1 - v2, sum >> 1 )
    }
    
    let result = calculate(v1:20 ,v2: 10)
    result.sum 
    result.differenceå
    result.average
    

    参数标签

    /// time 是形参名字
    /// at 是形参time的标签
    func goToWork(at time:String){
      print("this time is \(time)")
    }
    /// 标签的作用:使函数调用可读性更高
    goToWork(at:"8:00")
    
    /// 可以使用下划线 _ 省略参数标签
    
    func sum(_ v1:Int ,_ v2 : Int) {
      v1 + v2
    }
    sum(10,20)
    

    默认参数值

    func check(name: String = "nobody", age: Int, job: String = "none") {
      print("name=\(name) , age=\(age) , job=\(job)")
    }
    check(name:"liven",age=18,job:"programmer")
    check(age:15)
    

    可变参数

    /// 比如系统的print函数就是可变参数 
    /// 一个函数最多只能有一个可变参数
    /// 紧跟在可变参数后面的参数不能省略参数标签
    
    func sum(_ numbers: Int...) -> Int {
      var total = 0
      for number in numbers {
        total += number
      }
      return total
    }
    sum(10,20,30,40)
    

    输入输出参数

    可以使用inout定义一个输入输出参数:可以在函数内部修改外部实参的值
    可变参数不能标记为inout
    inout 参数不能有默认值
    inout参数的本质是地址传递(引用传递)
    inout 参数只能传入可以被多次赋值的(也就是说变量var)

    var number = 10
    
    func add(_ num: inout Int) {
      num = 20
    }
    
    add(&number)
    
    print(number)  /// 打印结果:20
    

    函数重载

    重载规则:
    函数名相同
    参数个数不同 或者 参数类型不同 或者 参数标签不同

    func sum(v1:Int ,v2:Int) -> Int {
      v1 + v2
    }
     
    func sum(v1:Int , v2: Int , v3: Int) -> Int {
      v1 + v2 + v3
    }    /// 参数个数不同
    
    func sum(v1: Int ,v2: Double) -> Int {
      Double(v1) + v2
    }  /// 参数类型不同
    
    func sum(_ v1:Int ,_ v2: Int) -> {
      v1 + v2
    }  /// 参数标签不同
    
    func sum(a: Int , b: Int) -> {
      a + b
    }  /// 参数标签不同
    
    

    重载注意点

    (1)返回值类型与函数重装无关

    /// 这两个函数名一样,但是一个有返回值一个没有,所以不能算重载
    func sum(v1: Int ,v2: Int) -> Int {
      v1 + v2
    }
    
    func sum(v1: Int, v2: Int) {
      v1 + v2
     }
    

    (2)默认参数值和函数重装一起使用产生二义性时,编译器并不会报错

    func sum(v1: Int , v2: Int) -> Int {
      v1 + v2
    }
    
    func sum(v1: Int ,v2: Int ,v3: Int = 10) -> Int {
      v1 + v2 + v3
    }
    
    /// 这会产生二义性,但是编译器不会报错
    sum(v1: 10 , v2: 20)
    

    (3)可变参数省略参数标签函数重装一起使用产生二义性时,编译器有可能会报错

    func sum(v1: Int ,v2 : Int) -> Int {
      v1 + v2
    }
    
    func sum(_ v1: Int , _ v2: Int) -> Int {
      v1 + v2
    }
    
    func sum(_ numbers: Int ...) - > Int {
      var total = 0
      for number in numbers {
        total += number
      }
      return total
    }
    

    函数的文档注释

    内联函数

    如果开启了编译器优化(Release模式默认会开启优化),编译器会自动将某些函数变成内联函数

    函数调用展开成函数体,比如下方

    func test() {
      print("test")
    }
    text()
    
    /// 编译器优化后,变成内联函数,直接变成如下
    print("test")
    

    哪些函数不会被内联?
    函数体比较长
    包含递归调用
    包含动态派发

    函数类型

    每一个函数都是有类型的,函数类型由形式参数类型返回值类型组成

    /// 这个函数的类型: () -> Void 或者 ()-> ()
    func text() {
    }
    
    /// 这个函数类型:(Int,Int) -> Int 
    func sum(a: In ,b: Int) -> Int {
      a + b
    }
    
    /// 使用函数类型,定义变量
    var fn: (Int ,Int) -> Int = sum
    /// 调用时不需要参数标签
    fn(2,3)
    
    

    函数类型作为函数参数

    func sum(v1:Int ,v2: Int) -> Int {
      v1 + v2  
    }
    
    func difference(v1: Int ,v2: Int) -> Int {
      v1 - v2
    }
    
    func printResult(_ mathFn: (Int ,Int ) -> Int, _ a : Int , _ b: Int) {
      print("Result:\(mathFn(a,b))")
    }
    
    /// Result:7
    printResult(sum,5,2)
    /// Result:3
    printResult(difference,5,2)
    

    函数类型作为函数返回值,返回值是函数类型的函数,叫做高阶函数

    func next(_ input: Int ) -> Int {
      input + 1
    }
    
    func previous(_ input: Int ) -> Int {
      input -1
    }
    
    func forward(_ forward: Bool) -> (Int) -> Int {
      forward ? next : previous
    }
    
    /// 结果: 4
    forward(true)(3)
    /// 结果: 2  
    forward(false)(3)
    

    typealias

    typealias用来给类型器别名

    typealias Byte = Int8
    typealias Short = Int16
    typealias Long = Int64
    
    /// 给元组起别名
    typealias Date = (year:Int , month: Int , day: Int)
    func test(_ data: Date) {
      print(date.0)
      print(date.year)
    }
    test((2011,9,10))
    
    
    /// 给函数类型起别名
    typealias IntFn = (Int , Int) -> Int
    func difference(v1: Int , v2: Int) -> Int {
      v1 - v2
    }
    let fn: IntFn = difference
    /// 返回值10
    fn(20,10)
    
    /// 作为参数
    func setFn(_ fn:IntFn) {}
    setFn(difference)
    
    /// 作为返回值
    func getFn() -> IntFn {
      difference
    }
    
    

    嵌套函数

    将函数定义在函数内部

    func forward(_ forward: Bool) -> (Int) -> Int {
      func next(_ input: Int) -> Int {
        input + 1
      }
      func previous(_ input: Int) -> Int {
        input -1
      }
      reture forwar ? next : previous
    }
    
    forward(true)(3)
    

    备注

    • 从Swift3开始,去除了自增(++)、自减(--)运算符
    • 按照Swift标准库的定义,Void就是空元组()

    相关文章

      网友评论

          本文标题:Swift5.0 小马哥_02流程控制、函数

          本文链接:https://www.haomeiwen.com/subject/wttynktx.html