zoukankan      html  css  js  c++  java
  • Swift -- 7.4 方法,下标,可选链

    方法

    swift统一了函数和方法的语法格式,如果函数放在枚举,结构体,类以外定义,就是函数

    如果放在枚举,结构体,类以内定义,就是方法

    程序可以直接把方法赋值给函数类型的变量

    class SomeClass {
        func test()
        {
            print("==test 方法==")
        }
        class func bar(msg:String) {
            print("==bar类型方法==, 传入参数为:(msg)")
        }
    }
    var sc = SomeClass()
    var f1 : ()->() = sc.test//这里不能加括号,添加括号就变成了方法调用,而不是将方法赋值给函数类型的变量
    var f2 : (String)->Void = SomeClass.bar
    sc.test()
    f1()
    SomeClass.bar("test message")
    f2("test test test message")
    

      

    结构体和枚举都是值类型,在默认情况下,值类型的实例方法不能改变该实例的存储属性,需要加mutating关键字

    struct FkRect {
        var x : Int
        var y : Int
        var width : Int
        var height : Int
        mutating func moveByX(x:Int, y:Int){
            self.x += x
            self.y += y
        }
    }
    var rect = FkRect(x: 20, y: 12,  200, height: 300)
    rect.moveByX(100, y: 80)
    print("(rect.x)")
    //可以使用可变方法直接改变枚举的实例
    enum Planettt:Int
    {
        case Mercury = 0, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Nepturn
        mutating func next(){
            if self.rawValue < 8 && self.rawValue > -1
            {
                self = Planettt(rawValue: self.rawValue + 1)!
            }
        }
        mutating func prev(){
            if self.rawValue < 8 && self.rawValue > -1
            {
                self = Planettt(rawValue: self.rawValue - 1)!
            }
        }
    }
    var pt = Planettt.Venus
    pt.next()
    pt.next()
    pt.prev()
    

      

    方法相当于一种以let声明的、类型为函数类型的存储属性

    分析:如果程序使用函数类型定义存储属性,并将函数或闭包作为该属性的初始值,那么这个属性变成了什么呢?没错,这个属性就成了方法

    func factorial(n:Int) ->Int
    {
        var result = 1
        for idx in 1...n
        {
            result *= idx
        }
        return result
    }
    struct SomeStruct {
        var info:()->Void={
            print("info")
        }
        static var fact:(Int) -> Int = factorial
    }
    var sccc = SomeStruct()
    sccc.info = {
        print("another bibo")
    }
    sccc.info()
    var n = 6
    print(SomeStruct.fact(6))
    SomeStruct.fact = {
        var result = 1
        for idx in 1...$0{
            result += idx
        }
        return result
    }
    print(SomeStruct.fact(6))
    

      

    下标

    下标和计算属性非常相似,但是下标比计算属性更灵活

    下标的形参列表不支持指定外部参数,也不支持指定默认值

    下标重载:一个类型可以包含多个下标,只要多个下标的形参列表不同(形参数量或者形参类型不同)

    可以通过扩展来增加下标

    struct FkRectt {
        var x : Int
        var y : Int
        var width : Int
        var height : Int
        subscript(idx : Int) -> Int{
            get{
                switch(idx)
                {
                case 0:
                    return self.x
                case 1:
                    return self.y
                case 2:
                    return self.width
                case 3:
                    return self.height
                default:
                    print("no")
                    return 0
                }
            }
            set{
                switch(idx)
                {
                case 0:
                    self.x = newValue
                case 1:
                    self.y = newValue
                case 2:
                    self.width = newValue
                case 3:
                    self.height = newValue
                default:
                    print("no")
                }
            }
        }
    }
    var rectc = FkRectt(x: 20, y: 12,  3435, height: 3453)
    rectc[0] = 40
    print(rectc[0])
    

      

    可选链

    class Companyy
    {
        var name = "feng"
        var addr = "guangzhou"
        init(name:String, addr:String){
            self.name = name
            self.addr = addr
        }
    }
    class Employeeee
    {
        var name = "bai"
        var title = "keke"
        var company : Companyy!
        init(name:String, title:String){
            self.name = name
            self.title = title
        }
        func info(){
            print("name is (name)")
        }
    }
    class Customerr
    {
        var name = ""
        var emp : Employeeee?
        init(name:String){
            self.name = name
        }
    }
    var cc = Customerr(name: "sunsun")
    var emp = Employeeee(name: "zhu", title: "kekefufu")
    cc.emp = emp
    emp.company = Companyy(name: "dandan", addr: "panpan")
    print("(cc.name) company is (cc.emp!.company.name)")
    /*
    那么问题来了
    如果这里的cc没有给emp赋值,那么输出语句会怎么样呢,会报错
    这时候可以通过在访问链中强制解析的感叹号(!)换成问号(?),在隐式解析和后面也添加问号(?)后缀,如果其中一个步骤返回nil,那么整个访问链都返回nil,而不会崩溃
    eg print("(cc.name) company is (cc.emp?.company?.name)")
    这就是可选链的访问方式
    */
    
    /*
    使用可选链调用方法
    */
    class Customeaa
    {
        var name = ""
        var emp : Employeeee?
        init(name:String){
            self.name = name
        }
        
        let employees = [
            Employeeee(name: "bai", title: "kefu"),
            Employeeee(name: "zhi", title: "xiaoshou"),
            Employeeee(name: "jin", title: "putonh"),
            Employeeee(name: "xing", title: "zhu")
        ]
        
        func findEmp(empName:String) -> Employeeee!
        {
            for emp in employees{
                if emp.name == empName{
                    return emp
                }
            }
            return nil
        }
    }
    var c3 = Customeaa(name: "fuck")
    c3.findEmp("bai").info()//这里没有使用可选链,但是name是存在的,所以不会报错,有输出
    c3.findEmp("ba")?.info()//这使用可选链来调用方法,虽然name是错误的,但是不会报错,也没有输出
    
    /*
    使用可选链调用下标
    */
    var dict = [Int : Customeaa]()
    dict[1] = Customeaa(name: "zhu")
    dict[2] = Customeaa(name: "sha")
    dict[1]?.findEmp("xing")?.info()
    dict[4]?.findEmp("xing")?.info()
    

      

  • 相关阅读:
    redhat 7.6 常用命令
    redhat 7.6 VI编辑操作
    redhat 7.6 网络配置
    华为学习配置笔记-01 配置con密码
    redhat 7.6 ssh 服务配置
    web前端面试第一次[addEventListenr();绑定事件]
    redis集群搭建
    linux服务器重启后redis数据丢失问题
    redis日志文件路径的设置
    linux下redis安装使用
  • 原文地址:https://www.cnblogs.com/chebaodaren/p/5591047.html
Copyright © 2011-2022 走看看