zoukankan      html  css  js  c++  java
  • Swift学习-Property

    可以在类、结构体、协议中定义属性,属性可以是变量,也可以是常量。 ###1.在结构体中声明属性:

    struct RectStore{
        var length : Int
        var breadth : Int
    }
    var r = RectStore(length:5,breadth:5)//length = 5
    r.length = 6//length = 6
    

    但因为结构体是值引用类型,所以当我们把结构体声明为常量时,是不可以改变结构体内部属性值的。如下:

    let r1 = RectStore(length: 5, breadth: 5)
    r1.length = 6 //报错:Cannot assign to property: 'r1' is a 'let' constant
    

    ###2.懒加载 定义为懒加载的属性

    struct Rect{
        
        var length : Int
        let breadth : Int
        
        init(length : Int, breadth: Int) {
            print("Rect struct is initialised now from the lazy var property")
            self.length = length
            self.breadth = breadth
        }
        
    }
    
    struct Square{
        
        var sidesEqual : Bool
        
        lazy var r = Rect(length: 6, breadth: 6)
        
        init(sidesEqual : Bool) {
            self.sidesEqual = sidesEqual
        }
    }
    var s = Square(sidesEqual: false)
    
    if s.sidesEqual
    {
        print(s.r.length)
    }
    else{
        print("Rect struct hasn't been initialised using the lazy var")  //this gets printed
    }
    //打印结果:Rect struct hasn't been initialised using the lazy var
    var s1 = Square(sidesEqual: true)
    
    if s1.sidesEqual
    {
        print(s1.r.length)
    }
    else{
        print("Rect struct hasn't been initialised using the lazy var") //not printed
    }
    //打印结果:Rect struct is initialised now from the lazy var property   
     6
    

    从上面的例子可以看出,懒加载会在调用之前在初始化。 ####2.1懒加载定义闭包

    class Name{
        var name : String?
        lazy var greet : String = {[weak self] in//为了防止循环引用,我们使用weak self
            guard let s = self else {
                return "Unable to unwrap self"
            }//防止循环引用
            guard let n = s.name else {
                return "No name found"
            }
            return "Hi, (n)"
        }()
        init(name : String){
            self.name = name
        }
    }
    var n = Name(name: "Anupam")
    print(n.greet)//打印结果:Hi, Anupam
    

    此时,我们把name置空,看看效果

    
    n.name = nil
    print(n.greet)//打印结果:Hi, Anupam
    

    发现打印结果没有改变,上述例子表明,懒加载只初始化一次;所以不论变量如何变化,闭包的结果是不变的. 再看个例子:

    //在举个例子
    var nn = Name(name : "Bobby")
    nn.name = nil
    print(nn.greet)//打印结果:No name found
    
    nn.name = "Bobby"
    print(nn.greet)//打印结果:No name found
    

    ###声明属性,在属性内部实现get、set方法;实现属性的读写

    struct Rectengle{
        var length : Double
        let breadth : Double
        var area : Double{
            get{//根据长框,算出面积;当外部直接调用area时,调用
                return length * breadth
            }
            set(newArea){//根据给定的面积、宽,计算出长;当外部给area赋值时调用
                length = newArea / breadth
            }
        }
    }
    
    var rs = Rectengle(length:6,breadth:5)
    print(rs.area)//打印结果:30.0 调用的是get方法
    
    rs.area = 40
    print(r.length)//打印结果:8.0 调用的是set方法
    //如果set方法中参数名不明确说明,Swift默认属性名为newValue,可以简化为下面方式
    struct RectangleSimply{
        
        var length : Double
        let breadth : Double
        
        var area : Double {
            
            get{
                return length*breadth
            }
            set
            {
                length = newValue/breadth
            }
        }
    }
    

    但是需要注意的是: 1、将实现了get、set方法的属性,定义为lazy var;也不能定义为常量。 2、定义了set方法的属性,必须定义get,不然会报错。 3、定义了get方法的属性,可以不定义set方法,此时,属性只支持读,不支持写。

    struct readOnlyRect{
        var length : Double
        var breadth : Double
        var area : Double{
            get{
                return length * breadth
            }
        }
        //周长
        var perimeter : Double{
            get{
                return length * 2 + breadth * 2
            }
        }
    }
    var rr = readOnlyRect(length:6,breadth:5)
    print(rr.area)//打印结果:30
    rr.area = 40 //报错,因为未实现,set方法;声明变量默认是包含get和set方法,只是读取的是变量本身的值。
    

    ###3.属性观察者 对属性变化做出响应,包含两个方法: (1)willSet:在值存储之前触发,它允许我们在值更改之前读取旧值。我们可以使用关键字newValue访问新值。 (2)didSet:在值存储之后触发,它允许我们读取新值和旧值。我们可以使用关键字oldValue访问旧值。 给属性set值时,会触发属性观察者。

    struct yardToInchesConversion{
        var yard : Double = 0{
            willSet{
                print("new value of yard (newValue)")
            }
            didSet{
                print("old value of yards (oldValue)")
                inches = yard * 36
                print("Updated value of inches (inches)")
            }
        }
        var inches : Double = 0
    }
    
    var yi = yardToInchesConversion()
    yi.yard = 22
    //打印结果:
    //new value of yard 22.0
    //old value of yards 0.0
    //Updated value of inches 792.0
    

    ###4.全局变量和静态变量 静态变量在子类中不能重写

    class A {
        var testNumner : Int = 10
        static var i : Int = 5
        static var name : String{
            return "Hello World"
        }
        class var multiplyByANumber: Int {
            return i * 5
        }
        static func printI(){
            print("Value of i is (i)")
        }
        class func appendClassName(){
            print("Class A Hello World")
        }
    }
    
    class SubClass : A{
        override class var multiplyByANumber : Int{
            return i * 5 * 5
        }
        override class func appendClassName(){
            print("Class SubClass Hello World")
        }
    }
    

    ###5.subscript 下标是访问集合、列表、序列元素的捷径,我们是用array[index]、dictionary[key]等,相应的,我们可以定义一个任意类型的下标。我们可以为同一类型定义多个下标,并根据传递给下标的索引值的类型选择要使用的适当下标重载。

    class M {
    private var month = ["Jan", "Feb", "March", "April"]
    subscript(index: Int) -> String {
        get {
            return month[index]
        }
        set(newValue) {
            self.month[index] = newValue
        }
    }
    }
    var m = M()
    m[3] //April
    m[0] = "Dec"
    
  • 相关阅读:
    宏任务与微任务
    reactnative 自定义项目的图标库
    react-native中textInput在androidTV上的焦点处理(坑篇)
    js中!!的运用
    ES6里class杂乱随笔
    浅析链式调用
    link和@import的区别
    ES2020链判断运算符?.和Null判断运算符??
    vue组件使用name属性来生成递归组件
    k8s学习——相关概念
  • 原文地址:https://www.cnblogs.com/PotatoToEgg/p/14976358.html
Copyright © 2011-2022 走看看