zoukankan      html  css  js  c++  java
  • swift 属性

    属性在前面的枚举,类,结构体中都已经使用过,本章介绍属性的性质和方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct FixedLengthRange {
        var firstValue: Int
        let length: Int
    }
    var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
    // the range represents integer values 0, 1, and 2
    rangeOfThreeItems.firstValue = 6
    // the range now represents integer values 6, 7, and 8
     
    //如果结构体的实例就是let类型,则第一次初始化后,不能再修改其任何属性的值
    let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
    // this range represents integer values 0, 1, 2, and 3
    rangeOfFourItems.firstValue = 6
    // 将会报错

    但是类不同意结构体,因为类是指针类型,将指针类型的实例赋值给一个常量,仍然可以修改其变量成员的值。

    延迟存储属性,在属性声明前部加@lazy关键字,必须是var类型的属性才能是延迟属性,延迟属性只有在用到时才会被计算。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class DataImporter {
        /*
        该类的功能是从外部文件导入数据
        */
        var fileName = "data.txt"
        // 其他数据导入等功能此处省略
    }
      
    class DataManager {
        @lazy var importer = DataImporter()
        var data = String[]()
        // 其他数据管理功能此处省略
    }
      
    let manager = DataManager()
    manager.data += "Some data"
    manager.data += "Some more data"
     
    //在下面的语句执行以前,importer未被创建
    println(manager.importer.fileName)
    // 当第一次用到importer的时候,才会生成实例,打印"data.txt"

    存储属性:我认为就是一般的属性,直接存储了变量或常量,可直接通过后点(.)获得或设置其值

    计算属性:有get方法和set(可选)方法的属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    struct Point {
        var x = 0.0, y = 0.0
    }
    struct Size {
        var width = 0.0, height = 0.0
    }
    struct Rect {
        var origin = Point()
        var size = Size()
        var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set(newCenter) {
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
        }
        }
    }
    var square = Rect(origin: Point(x: 0.0, y: 0.0),size: Size( 10.0, height: 10.0))
    //调用了center的get方法,计算了Point
    let initialSquareCenter = square.center
    //调用了center的set方法,origin被修改了
    square.center = Point(x: 15.0, y: 15.0)
    println("square.origin is now at ((square.origin.x), (square.origin.y))")
    // origin现在是 (10.0, 10.0)

    set方法可以省略参数,省略时,默认用newValue代替,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    struct AlternativeRect {
        var origin = Point()
        var size = Size()
        var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set {
            origin.x = newValue.x - (size.width / 2)
            origin.y = newValue.y - (size.height / 2)
        }
        }
    }

    只有get方法的计算属性是只读的,可以省略get,语法如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct Cuboid {
        var width = 0.0, height = 0.0, depth = 0.0
        var volume: Double {
        return width * height * depth
        }
    }
    let fourByFiveByTwo = Cuboid( 4.0, height: 5.0, depth: 2.0)
    println("the volume of fourByFiveByTwo is (fourByFiveByTwo.volume)")
    // 打印"the volume of fourByFiveByTwo is 40.0"

    属性监视器,允许开发者在设置变量值前后执行一段代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    class StepCounter {
        var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            println("About to set totalSteps to (newTotalSteps)")
        }
        didSet {
            //参数省略时,默认使用oldValue,willSet的参数也可省略,默认是newValue
            //在didSet方法里也可以修改本属性的值,并且在次数的赋值不调用willSet和didSet
            if totalSteps > oldValue  {
                println("Added (totalSteps - oldValue) steps")
            }
        }
        }
    }
    let stepCounter = StepCounter()
    //每设置一次totalSteps 的值,都执行willSet和didSet各一次,初始化时都不执行
    stepCounter.totalSteps = 200
    // About to set totalSteps to 200
    // Added 200 steps
    stepCounter.totalSteps = 360
    // About to set totalSteps to 360
    // Added 160 steps
    stepCounter.totalSteps = 896
    // About to set totalSteps to 896
    // Added 536 steps

    全局变量一般都是计算延迟的,类似延迟存储变量, 但是不需要在前面加@lazy关键字

    类型属性就是属于类型的属性,想C++中静态变量,只存在一份,在所有类的实例中共享。

    值类型(结构体和枚举)可以定义存储变量和计算变量的类型属性,而指针类型(类)只能定义计算变量的类型属性

    而存储类型属性可以是var和let型的,而计算类型属性只能是var型的

    必须给存储类型属性赋初值,因为类型在初始化不能对存储类型属性赋值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    //声明类型属性
    struct SomeStructure {
        static var storedTypeProperty = "Some value."
        static var computedTypeProperty: Int {
        // return an Int value here
        }
    }
    enum SomeEnumeration {
        static var storedTypeProperty = "Some value."
        static var computedTypeProperty: Int {
        // return an Int value here
        }
    }
    class SomeClass {
        class var computedTypeProperty: Int {
        // return an Int value here
        }
    }
    //使用和赋值类型属性,使用类型调用类型属性
    println(SomeClass.computedTypeProperty)
      
    println(SomeStructure.storedTypeProperty)
    // 打印 "Some value."
    SomeStructure.storedTypeProperty = "Another value."
    println(SomeStructure.storedTypeProperty)
    // 打印"Another value."
  • 相关阅读:
    SQL练习题9:获取所有部门当前(dept_manager.to_date='9999-01-01')manager的当前(salaries.to_date='9999-01-01')薪水情况,给出dept_no, emp_no以及salary(请注意,同一个人可能有多条薪水情况记录)
    SQL练习题8:找出所有员工当前(to_date='9999-01-01')具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示
    数据仓库、数据集市、数据湖、数据中台概念理解
    SQL练习题七:查找薪水变动超过15次的员工号emp_no以及其对应的变动次数t
    SQL练习题6:查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序(请注意,一个员工可能有多次涨薪的情况)
    SQL练习五:查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括暂时没有分配具体部门的员工(请注意输出描述里各个列的前后顺序)
    SQL练习题四:查找所有已经分配部门的员工的last_name和first_name以及dept_no(请注意输出描述里各个列的前后顺序)
    SQL练习题三: 查找各个部门当前(dept_manager.to_date='9999-01-01')领导当前(salaries.to_date='9999-01-01')薪水详情以及其对应部门编号dept_no (注:请以salaries表为主表进行查询,输出结果以salaries.emp_no升序排序,并且请注意输出结果里面dept_no列是最后一列)
    SQL练习题二:查找入职员工时间排名倒数第三的员工所有信息,为了减轻入门难度,目前所有的数据里员工入职的日期都不是同一天
    [CF1379E]Inverse Genealogy
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/5066870.html
Copyright © 2011-2022 走看看