Swift小结

作者: 春暖花已开 | 来源:发表于2018-11-26 22:11 被阅读11次

不同的字符可能会占用不同数量的内存空间,所以要知道Character的确定位置,就必须从String开头遍历每一个 Unicode 标量直到结尾。因此,Swift 的字符串不能用整数(integer)做索引。

如果两个字符串(或者两个字符)的可扩展的字形群集是标准相等的,那就认为它们是相等的。在这个情况 下,即使可扩展的字形群集是有不同的 Unicode 标量构成的,只要它们有同样的语言意义和外观,就认为它们标 准相等。

var oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]

oddDigits.union(evenDigits).sorted() // 取并集
oddDigits.subtract(singleDigitPrimeNumbers) // 剔除交集
evenDigits.symmetricDifference(singleDigitPrimeNumbers).sorted() // 交集取反
图片.png

必须将延迟存储属性声明成变量(使用var关键字),因为属性的初始值可能在实例构造完成之后才会得到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。

当值类型(枚举、结构体)的实例被声明为常量的时候,它的所有属性也就成了常量。属于引用类型的类(class)则不一样。把一个引用类型的实例赋给一个常量后,仍然可以修改该实例的变量属性。

必须使用var关键字定义计算属性,包括只读计算属性,因为它们的值不是固定的。let关键字只用来声明常量属性,表示初始化后再也无法修改的值。

跟实例的存储型属性不同,必须给存储型类型属性指定默认值,因为类型本身没有构造器,也就无法在初始化过程中使用构造器给类型属性赋值。存储型类型属性是延迟初始化的,它们只有在第一次被访问的时候才会被初始化。即使它们被多个线程同时访问,系统也保证只会对其进行一次初始化,并且不需要对其使用lazy修饰符。

func stepForward(_ input: Int) -> Int {
    return input + 1
}

func stepBackward(_ input: Int) -> Int {
    return input - 1
}


func cal(isAdd: Bool) -> (Int) -> Int {
    if isAdd {
        return stepForward
    }
    return stepBackward
}

// 等价于

func caculate(isAdd: Bool) -> (Int) -> Int {
    if isAdd {
        func stepFor(input: Int) -> Int {
            return input + 1
        }
        return stepFor
    } else {
        func stepBack(input: Int) -> Int {
            return input - 1
        }
        return stepBack
    }
}

// 调用1
cal(isAdd: true)(1)
// 调用2
caculate(isAdd: true)(1)

类型属性语法

在 C 或 Objective-C 中,与某个类型关联的静态常量和静态变量,是作为全局(global)静态变量定义的。但 是在 Swift 中,类型属性是作为类型定义的一部分写在类型最外层的花括号内,因此它的作用范围也就在类型支 持的范围内。
使用关键字 static 来定义类型属性。在为类定义计算型类型属性时,可以改用关键字 class 来支持子类对父 类的实现进行重写。

例如:

struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 1
    }
}

enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 6
    }
}

class SomeClass {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27
    }
    class var overrideableComputedTypeProperty: Int {
        return 107
    }
}
获取和设置类型属性的值

跟实例属性一样,类型属性也是通过点运算符来访问。但是,类型属性是通过类型本身来访问,而不是通过实
例。

例如:

print(SomeStructure.storedTypeProperty) // 打印 "Some value." 
SomeStructure.storedTypeProperty = "Another value." print(SomeStructure.storedTypeProperty) // 打印 "Another value.” 
print(SomeEnumeration.computedTypeProperty) // 打印 "6" 
print(SomeClass.computedTypeProperty) // 打印 "27"

在实例方法中修改值类型

结构体和枚举是值类型。默认情况下,值类型的属性不能在它的实例方法中被修改。
但是,如果你确实需要在某个特定的方法中修改结构体或者枚举的属性,你可以为这个方法选择 可变(mutatin g) 行为,然后就可以从其方法内部改变它的属性;并且这个方法做的任何改变都会在方法执行结束时写回到原始 结构中。方法还可以给它隐含的 self 属性赋予一个全新的实例,这个新实例在方法结束时会替换现存实例。

例如:如果没有mutating,将报错Left side of mutating operator isn't mutable: 'self' is immutable

struct Point {
    var x = 0.0, y = 0.0
    mutating func moveByX(deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}

枚举的可变方法可以把 self 设置为同一枚举类型中不同的成员:

例如:

enum TriStateSwitch {
    case Off, Low, High
    
    mutating func next() {
        switch self {
        case .Off:
            self = .Low
        case .Low:
            self = .High
        case .High:
            self = .Off
        }
    }
}

var ovenLight = TriStateSwitch.Low
ovenLight.next() // ovenLight 现在等于 .High
ovenLight.next() // ovenLight 现在等于 .Off

类型方法

实例方法是被某个类型的实例调用的方法。你也可以定义在类型本身上调用的方法,这种方法就叫做类型方 法。在方法的 func 关键字之前加上关键字 static ,来指定类型方法。类还可以用关键字 class 来允许子类重写 父类的方法实现。

注意

在 Objective-C 中,你只能为 Objective-C 的类类型(classes)定义类型方法(type-level methods)。在 Swift 中,你可以为所有的类、结构体和枚举定义类型方法。每一个类型方法都被它所支持的类型显式包含。


重写属性

你可以重写继承来的实例属性或类型属性,提供自己定制的 getter 和 setter,或添加属性观察器使重写的属性 可以观察属性值什么时候发生改变。
重写属性的 Getters 和 Setters
你可以提供定制的 getter(或 setter)来重写任意继承来的属性,无论继承来的属性是存储型的还是计算型的 属性。子类并不知道继承来的属性是存储型的还是计算型的,它只知道继承来的属性会有一个名字和类型。你在 重写一个属性时,必需将它的名字和类型都写出来。这样才能使编译器去检查你重写的属性是与超类中同名同类 型的属性相匹配的。
你可以将一个继承来的只读属性重写为一个读写属性,只需要在重写版本的属性里提供 getter 和 setter 即 可。但是,你不可以将一个继承来的读写属性重写为一个只读属性。

注意

如果你在重写属性中提供了 setter,那么你也一定要提供 getter。如果你不想在重写版本中的 getter 里修改 继承来的属性值,你可以直接通过 super.someProperty 来返回继承来的值,其中 someProperty 是你要重写的属 性的名字。

相关文章

  • swift基础小结1

    swift基础小结 for 循环OC与Swift对比 While循环与downhill循环 OC与swift使用的...

  • swift-循环

    循环 OC风格的 for Swift风格的 for 阶段性小结Swift 中使用 in 关键字标示循环的范围0.....

  • Swift3.0 函数闭包与 Block

    最近新接手了一个Swift项目,花点时间做点小结,以做记录我的博客链接 Swift中定义一个基本函数 Swift ...

  • 3.Swift-循环

    OC风格的 for Swift风格的 for 阶段性小结Swift 中使用 in 关键字标示循环的范围0..<10...

  • Swift开发体验

    代码实现 对比与小结 Swift 文件都是以 .swift 结尾 没有 main.m 文件 代码全部都放在大括号里...

  • Swift 小结

    Selector Extension CoreText CTFrameCTLineCTRun: 是每一个相同属性字...

  • Swift小结

    懒加载 格式 lazy var 变量: 类型 = { 创建变量代码 }() 以 lazy var 开头,闭包末尾跟...

  • Swift小结

    基本语法: 定义变量和常量: let 和 var常量和变量的命名:你可以使用任何你喜欢的字符作为常量和变量名,包括...

  • Swift小结

    不同的字符可能会占用不同数量的内存空间,所以要知道Character的确定位置,就必须从String开头遍历每一个...

  • Swift小结

    //TODO: 用于标记未完成的任务// FIXNE: 用于标记待修复的问题//#warning("todo") ...

网友评论

    本文标题:Swift小结

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