Swift3.0进阶知识笔记

Swift3.0进阶知识笔记

五月 20, 2019

#Swift3.0进阶知识

函数


  • 可以为函数参数设定默认值,炮塔的位置固定,可将其设为默认值,只传入一个参数即可

  • 游戏中敌人距离炮塔的距离,已确定是否攻击

    'var str = "Hello, playground"
      func getDistance(enemyPosition:CGPoint,turretPosition:CGPoint=CGPoint(x:100,y:100))->CGFloat
      {
    let Xdis = turretPosition.x - enemyPosition.x
    let Ydis = turretPosition.y - enemyPosition.y
    return sqrt(pow(Xdis, 2)+pow(Ydis, 2))
      }
      let enemyPositiion = CGPoint(x:200,y:200)//敌人位置
      let distance = getDistance(enemyPosition: enemyPositiion)
      print(distance)
    
      let eeemyPostiion = CGPoint(x: 200, y: 200)//敌人位置
      let anotherturretPosition = CGPoint(x: 100, y: 400)//另一个炮塔位置
      let distance_1 = getDistance(enemyPosition: eeemyPostiion, turretPosition: anotherturretPosition)
      print(distance_1)'
  • 简单的一个算数运算函数

    func sum(number1:Int,number2:Int)->Int
      {
    return number1+number2
      }
      let result_a = sum(number1: 2, number2: 4)//函数调用传入参数2与4
      let result_b = sum(number1: 1, number2: 4)//函数调用传入参数1与4
  • 设置可变的函数参数数量

  • 在定义函数时,不确定参数的数量,通过在变量类型后加(…),定义可变参数。

  • 一个函数只能有一个可变参数,必须放在函数表的最后一个

    func getAverage(numbers:Double...)->Double
      {
    if numbers.count==0//防止除0 error
    {
        return 0.0
    }
    else
    {
        var  total:Double = 0
        for number in numbers
        {
            total+=number
        }
        return total/Double(numbers.count)
        }
      }
      let average2 = getAverage()
    
      let average1 = getAverage(numbers: 1,2,3,4,5,6,7)//调用getAverage()方法,并传入参数(1,2,3,4,5,6,7)'
  • 函数作为参数和返回类型

    func getSmaller(number_q:Int,number_w:Int)->Int//获取最小值方法
      {
    return (number_q<number_w) ? number_q:number_w
      }
      func getBigger(number_e:Int,number_r:Int)->Int//获取最大值方法
      {
    return (number_e>number_r) ? number_e:number_r
      }
      func printMathResult(mathFunction:(Int,Int)->Int,num1:Int,num2:Int)//第一个参数选择执行那个函数,参数类型为(Int,Int)->Int,拥有两个Int类型的参数,和返回整形结果的函数类型,来处理后面两个参数
      {
    print("The result is:\(mathFunction(num1,num2))")
      }
      printMathResult(mathFunction: getSmaller, num1: 1, num2: 3) //选择getSmaller方法
      printMathResult(mathFunction: getBigger, num1: 3, num2: 6)//选择getBigger方法
  • 函数作为返回类型

    func chooseFunction(needBigger:Bool)->(Int,Int)->Int
      {
    return needBigger ? getBigger:getSmaller
    
      }
      let function = chooseFunction(needBigger: true)//将函数赋予常量function,使其具有获得较大参数的功能。
      print(function(2,3))
  • 元祖作为函数的返回值类型,实现多的返回值

    func getUserInfo(userID:String)->(userName:String,userLevel:Int,photoPath:String)
      {
    let userNmae = "Jhon"
    let userLevel = 3
    let photoPath = "http://www.wmweb.com/userphoto/me.png"
    return (userNmae,userLevel,photoPath)
    
      }
      let message_i = getUserInfo(userID: "2341")
      print(message_i)
      print(message_i.0)
      print(message_i.1)
      print(message_i.2)
  • 使用函数类型

    func getTotal(num_a:Int,num_s:Int)->Int//一个普通函数
      {
    return num_s + num_a
        }
      let newFunction:(Int,Int)->Int = getTotal//定义一个变量,其类型时两个整型参数,并返回整形的函数,并指向getTotal函数
      let result = newFunction(1,1)
      print(result)
    
      let anotherFunction = getTotal//再给函数类型定义变量时,可省略函数类型的书写
      let result1 = anotherFunction(1,1)
      print(result1)
    
      func printHelloSwift()//使用无参数且无返回值的函数类型
      {
    print("Hello Swift!")
      }
      let anotherGreating:()->() = printHelloSwift
      print(anotherFunction)
  • 函数的输入输出参数

  • 如果想要一个函数可以修改参数的值,并且这些修改在函数调用结束后任然存在,那就可以将参数定义为输入输出参数,这个一通过在参数类型的前面添加inout关键字实现

  • 传入函数的参数只能是变量,当传入的参数作为输入输出参数时,需要在参数前面加上&符号,表示这个参数值时可以被修改的

    func swap(prevNumber:inout Double,nextNumber:inout Double)//prevNumber and nextNumber 都拥有inout关键字,都为输入输出参数。
      {
    let tempNumber = prevNumber //定义临时常量tempNumber交换两个输入输出参数的值
    prevNumber = nextNumber
    nextNumber = tempNumber
    
      }
      var prevNumber = 1
      var nextNumber = 3
      swap(&prevNumber, &nextNumber)//调用swap()时,系统会自动为连个输入输出参数左边加上&
      //函数调用结束
      print(prevNumber)//修改依然存在
      print(nextNumber)
  • 函数的嵌套,在父函数下调用,外部无法调用

    func chooseFunction(needBigger:Bool,number_d:Int,number_f:Int)
      {

    func getSmaller(number3: Int, number4: Int)

    {
        print((number3<number4) ? number3:number4)
    }
    func getBigger(number3:Int,Number4:Int)
    {
        print((number3<Number4) ? number3:Number4)
    }
    needBigger ? getSmaller:getBigger
      }
      let newFunction1:(Bool,Int,Int)->() = chooseFunction//函数类型
      print(newFunction1(true,4,6))
  • 函数的递归:自调用函数;直接或间接的调用函数自身

    func recursion(n:Int)->Int
        {
    if n<=1 { //执行8次
        return 2
    }
    else
    {
        return recursion(n: n-1) * recursion(n: n-2)//递归语句执行了7次,导致148行执行了8次,从而使8个2想乘,得到结果256
    }
    
      }
      print(recursion(n: 5))
  • 常用的内置函

    print(abs(-100))//绝对值函数
      print(pow(2, 10))//指数函数
      print(sqrt(pow(3, 2) + pow(4, 2)))//平方根函数求勾股定理
      print(min(2, 3,8,0,15))//最小值函数
      print(max(23,56,23, 52))//最大值函数
  • filter函数常用于查找在数组元素中,满足指定条件的元素//这里是查找1到10中能被3整除的数字({$0%3==0}为筛选闭包,$0为默认参数,返回类型隐式推断为Bool类型)

    for i in (1...10).filter({$0%3==0})
      {
    print(i)
        }
        for i in [23,9,3,6,78,56].filter({$0%3==0})
        {
    print(i)
    
      }
  • map函数通常用于将数组中的每个元素通过指定的方法进行转换。//这里把1到5的数都乘以3遍历出来
    for i in (1...5).map({$0*3}) {
    print(i)
      }
  • reduce函数可以把数组元素组合计算为一个值,
    let result_z = (1...10).reduce(0, {$0+$1})// {$0+$1}可缩写为+ ,第一个参数表示从多少开始,此处从0开始
        print(result_z)
      let result_x = (1...100).reduce(0, +)
      print(result_x)
      let result_c = (1...10).reduce(1, *)//此处从1开始,从零开始,结果就为零了
      print(result_c)

枚举


  • 事先考虑某一变量的可能取值范围尽量用自然语言中含义清楚的单词来表示他的每一个值,这种方法叫做枚举方法,类型叫做枚举类型,定义用enum关键字,枚举成员在一对大括号中

  • 通过case关键字明确定义的成员值,枚举名称用驼峰命名,枚举成员在被创建时,不会赋值一个默认的整数值,

  • 枚举只限于在列举出来的范围内进行取值,有限的,支持字符串,字符,整数和浮点数

    enum UserLevel
      {
    case 总经理
    case 区域经理
    case 主管
    case 业务员
      }

    //当枚举成员比较少时可将枚举成员放置在一行中
    /*

    enmu userLevel
    {
    case 总经理,区域经理,主管,业务员
    }

    */

    print(UserLevel.总经理)
    var userLevel = UserLevel.业务员
    userLevel = .主管
  • 当变量userLevel被声明为UserLevel枚举类型时,设定他的值时可以不必在写类型名,即用更快捷的点(.)就可以修改为另一个UserLevel的成员值

  • 枚举的遍历:通常使用switch语句进行枚举类型的遍历操作

    switch userLevel
       {
        case UserLevel.总经理:
    print("总经理登录系统后,进行系统配置页面。")
        case UserLevel.区域经理:
    print("区域l经理录系统后,进行系统配置页面。")
        case UserLevel.主管:
    print("主管登录系统后,进行系统配置页面。")
        case UserLevel.业务员:
    print("业务员登录系统后,进行系统配置页面。")
        }
  • 一般用switch语句是对所有的枚举值全部覆盖的,否则,就需要使用default语句,以包含未被处理的枚举值。

    switch userLevel {
      case UserLevel.总经理:
        print("总经理登录系统后,进行系统配置页面。")
      case UserLevel.区域经理:
        print("区域l经理录系统后,进行系统配置页面。")

    /*case UserLevel.主管:

        print("主管登录系统后,进行系统配置页面。")*/
    case UserLevel.业务员:
        print("业务员登录系统后,进行系统配置页面。")
    default:  //Default will never be executed(默认永远不会执行)(当枚举值在的时候)
        print("无法进入客户报备页面,请重新登录!")
    }
  • 枚举的原始值

    /*enum Gender:UInt8 //gender:性别
        {
    case Male = 1
    case Female = 2
    case Unknow = 3
      }
  • 不必显示的为每个枚举值分配一个原始值,如下Male = 1,则后面每个成员的隐式值都比前一个大1,swift会自动分配,第一个成员没有值时,默认为零

    enum Gender:UInt8
    {
    case Male = 1,Female,Unknow
    }
    //可以用rawValue属性来访问一个枚举成员的原始值
    print(Gender.Female.rawValue) //rawvalue:原始值
    //如果用原始值类型定义一个枚举,那么枚举就会自动收到一个可以接受原始值类型的值得初始化器,然后返回一个枚举成员或者nil
    let gender = Gender(rawValue: 2)
    print(gender!)
    //给枚举添加方法:于其他语言不同的是,枚举可以添加方法扩展枚举的功能
    enum Gender1:UInt8
    {

    case Male,Female,Unknow
    func description()
    {
    switch self {
    case .Female: //枚举案例“女性”不能用作实例成员
        print("Hi,lady!")
    
    case .Male:
        print("Hi,Man!")
    case .Unknow:
        print("Hi,....")
    }
    }

    }
    let gender1 = Gender1.Female//对枚举实例化
    gender1.description()

结构体


  • 可以为结构体定义常量和变量,还可以为结构体添加方法来扩展结构体的功能。以关键字struct来进行定义,将内容放置在一对大括号中。
    struct Animal
      {
    let zoomNmae:String = "Beijing zoom"
    var name:String
      }
    //对结构体实例化
    var animal = Animal(name: "Tiger")
    print(animal)
    print(animal.name)
    //修改结构体实例
    animal.name = "Elephant"
    print(animal)
    //注意:类是引用类型,而结构体和枚举都是值类型,值类型是一种当被指定为常量或者变量,或者着传递给函数时会被拷贝的类型。
    let firstAnimal = Animal(name: "Monker")
    var secondAnimal = firstAnimal
    secondAnimal.name = "Elephant"
    print(firstAnimal.name)
    print(secondAnimal.name)
    //可见当secondAnimal的值修改了,而firstAnimal的未被修改
    //给结构体添加方法
    struct Animal1
    {
    let zoomNmae:String = "Beijing zoom"
    var name:String
    func say()
    {
        print("Hi ,I'm \(name).")
    }
    }
    let tiger = Animal1(name: "Tiger")
    tiger.say()
  • 结构体的下标
    //结构体,枚举,类都可以定义下标,可以作为访问集合、列表、或序列成员元素的快捷方式。
    //可以使用下标通过索引值来设置或检索值,而不需要为设置和检索值来分别使用实例方法。
    //实用关键字subscript(标)来定义下标

    struct MySubscript
    {
    var number:Int
    subscript(n:Int)->Int //定义一个下标,传入一个整形参数,将结构体的属性乘以n倍h🐵返回结果
    {
        return number*n
    }
    
    }
    let subScript = MySubscript(number: 4)//实例化结构体,并设置实例的number参数值为4
        print(subScript[3])//使用下标的方法获得number属性值乘以3后的乘积


  • 用户自定义的数据类型,具有一定的行为能力,包含两部分内容:属性和方法 和结构体极为相似,都有属性和方法,但类是引用类型,而结构体是值类型
    //与其他语言不同的是,swift并不要求你为自定义类去创建独立的接口和实现文件,你所要做的就是在一个单一文件中定义一个类,系统会自动生成面向其他代码的外部接口
    //类用关键字class作为关键字,把内容放在一对大括号中,swift要求定义类时要对属性进行初始化

    class Car
    {
    var brand:String = ""
    var spend:Int = 0
}