Swift之旅_Language Guide2

刚做完一个项目,有点时间,就把Swift官方文档的部分小节阅读了一下,照例记录一些知识盲点和重点。


Enumerations

这一小节主要讲解的是Swift中枚举的相关用法。Swift中的枚举不像C中的枚举的case关联的值只能是数值,Swift中枚举case的关联值可以是各种各样的值,并且可以直接通过枚举的rawValue属性获取它。

enum kStatusEnum: Int {
    case success = 200
    case failed = 404
}
print(kStatusEnum.success.rawValue)
print(kStatusEnum.failed.rawValue)
// print 200, 404
  • Recursive Enumerations

此外还有一个比较高端的用法(个人感觉= =),可以在枚举中使用递归。在枚举前加上indirect修饰符可以让枚举中的每个case都是可递归的,或者单独在某个case里加上这个修饰符,表示该case是可递归的。

indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}

let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

func evaluate(_ expression: ArithmeticExpression) -> Int {
    switch expression {
    case let .number(value):
        return value
    case let .addition(left, right):
        return evaluate(left) + evaluate(right)
    case let .multiplication(left, right):
        return evaluate(left) * evaluate(right)
    }
}
 
print(evaluate(product))
// Prints "18"

Classes and Structures

这一小节主要讲解的是Swift中类和结构体的用法,Swift不用像其他编程语言需要在头文件中声明属性和方法,你可以在单个文件中定义类或结构,并且该类或结构的外部接口可以自动供其他代码使用。此外,Swift中结构体与类有许多共同之处。

  • Memberwise Initializers for Structure Types

All structures have an automatically-generated memberwise initializer, which you can use to initialize the member properties of new structure instances. Initial values for the properties of the new instance can be passed to the memberwise initializer by name:

Swift中所有结构体都会有自动生成一个初始化方法为每个属性分配值,你可以使用它初始化新结构实例的成员属性,如下代码只声明了结构体的属性,但是也会自动生成一个初始化方法,改方法可以为结构体中的每个属性分配一个值。

struct Person {
    var name: String?
    var age: String?
}
var p = Person(name: <#T##String?#>, age: <#T##String?#>)
  • Structures and Enumerations Are Value Types

All structures and enumerations are value types in Swift. This means that any structure and enumeration instances you create—and any value types they have as properties—are always copied when they are passed around in your code.

在Swift中所有的结构体和枚举都是值类型。这意味着你创建的所有的结构体和枚举(以及任何作为他们属性的值类型)在你的代码中传递时总是是copy的。

override func viewDidLoad() {
    super.viewDidLoad()
    let objInstance = testClass()
    var structInstance1 = testStruct(age: 25, obj: objInstance)
    var structInstance2 = structInstance1
    structInstance2.age = 30
}
struct testStruct {
    var age: Int?
    var obj: testClass?
}
class testClass: NSObject {
}

如上代码,自定义了一个结构体有一个Int类型的属性,和一个testClass对象属性,代码中初始化了一个objInstance实例对象objInstance,并用objInstance去初始化了一个testStruct类型的结构体structInstance1,然后又把structInstance1赋值给了另外一个结构体structInstance2,最后修改了structInstance1的age属性,调试得出以下结果:

可以看到structInstance2 的age修改之后structInstance1的age并没有改变,说明结构体在Swift中确实是值类型。此外关于"(以及任何作为他们属性的值类型)"在图中也有体现,obj是一个引用类型,所以在copy过程中并没有分配新的存储空间,而是引用了objInstance。

  • Classes Are Reference Types

类是引用类型的。

let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0

let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
// Prints "The frameRate property of tenEighty is now 30.0"
  • Identity Operators

Identical to (===)
Not identical to (!==)
使用这些运算符检查两个常量或变量是否引用同一个实例:

let view1 = UIView()
let view2 = UIView()
let view3 = view1       
print(view1 === view2)
print(view1 === view3)
//false     true

至于==和===有什么区别,官方文档上有这么一句话.

Note that “identical to” (represented by three equals signs, or ===) does not mean the same thing as “equal to” (represented by two equals signs, or ==):
“Identical to” means that two constants or variables of class type refer to exactly the same class instance.
“Equal to” means that two instances are considered “equal” or “equivalent” in value, for some appropriate meaning of “equal”, as defined by the type’s designer.

“相同”表示两个常量或类类型的变量引用完全相同的类实例。
“相等”意味着两个实例在价值上被认为是“相等的”或“等价的”,这是由“类型”设计者定义的“相等”的适当含义。
还是不太理解二者的区别,不过后面会有讲解,如果有懂的大神希望可以指点一下.

  • Pointers

If you have experience with C, C++, or Objective-C, you may know that these languages use pointers to refer to addresses in memory. A Swift constant or variable that refers to an instance of some reference type is similar to a pointer in C, but is not a direct pointer to an address in memory, and does not require you to write an asterisk (*) to indicate that you are creating a reference. Instead, these references are defined like any other constant or variable in Swift.

对于指针这一块,文档上暂时只有这么一段话描述,Swift中引用某些引用类型的实例常量或实例变量类似于C中的指针,但不是指向内存中地址的直接指针。

最后有段话也值得记录一下:

Assignment and Copy Behavior for Strings, Arrays, and Dictionaries
In Swift, many basic data types such as String, Array, and Dictionary are implemented as structures. This means that data such as strings, arrays, and dictionaries are copied when they are assigned to a new constant or variable, or when they are passed to a function or method.

This behavior is different from Foundation: NSString, NSArray, and NSDictionary are implemented as classes, not structures. Strings, arrays, and dictionaries in Foundation are always assigned and passed around as a reference to an existing instance, rather than as a copy.

在SWIFT中,许多基本数据类型(如字符串、数组和字典)被实现为结构体。这意味着当字符串、数组和字典被分配给一个新的常量或变量时,或者当它们被传递给函数或方法时,他们都是被copy的。
不同于Foundation框架中的NSString,NSArray,和NSDictionary,他们都是类,不是结构体。所以Foundation中的 字符串,数组,和字典在分配和传递时通常是引用的形式而不是copy。


Properties

这一小节主要讲解的是Swift中的属性。这一小节的知识点不多,主要是属性的get set willSet 和 didSet的使用。
值得注意的是一个static和class的区别。我平时开发中都有过用static和class去定义一个类方法,之前也不太了解两者的区别,看到官方文档中有提及,但是限于英文水平有限去查阅了一些资料发现,class定义的方法可以被子类重写,而static的不能(感觉相当于calss final)。

class ClassA {
    class func func1() -> String {
        return "func1"
    }
    static func func2() -> String {
        return "func2"
    }
    class final func func3() -> String {
        return "func3"
    }
} 
class ClassB : ClassA {
    override class func func1() -> String {
        return "func1 in ClassB"
    }
    // ERROR: Cannot override static method
    override static func func2() -> String {
        return "func2 in ClassB"
    }
    // ERROR: Class method overrides a 'final` class method
    override class func func3() -> String {
        return "func3 in ClassB"
    }
} 

Methods

这一小节主要讲解的是Swift中方法的相关用法。
和oc不同的是,Swift中结构体和枚举也可以定义方法。

struct Point {
    var x = 0.0, y = 0.0
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
// Prints "The point is now at (3.0, 4.0)"

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 is now equal to .high
ovenLight.next()
// ovenLight is now equal to .off

关于mutating(变异方法)在第一篇文章Swift之旅_Welcome to Swift有提到过中有提及过,可以参考一下。


Subscripts

这一小节主要讲解了Swift中下标的语法,不看还真不知道Swift中下标可以这样用。
以前只知道数组和字典可以用下标语法,但是在Swift中,类、结构体和枚举都可以定义自己的下标。

  • Subscript Syntax

为结构体定义下标,这样用起来感觉像是数组= =。在结构体、枚举和类中的方法都如下:

struct TimesTable {
    let multiplier: Int
    subscript(index: Int) -> Int {
        return multiplier * index
    }
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])")
// Prints "six times three is 18"

也可以在subscript中传入多个参数

struct Matrix {
    let rows: Int, sections: Int
    subscript(section: Int, row: Int) -> Int {
        return section * rows + row
    }
}
let threeTimesTable = Matrix(rows: 10, sections: 5)
print(threeTimesTable[2,5])
// 25

Inheritance

这一小节主要讲解的是Swift中的继承。基本没啥难度,大部分是在讲重写属性、方法、下标。不过最后倒是有一个修饰符以前没注意过。

  • Preventing Overrides

You can prevent a method, property, or subscript from being overridden by marking it as final. Do this by writing the final modifier before the method, property, or subscript’s introducer keyword (such as final var, final func, final class func, and final subscript).
Any attempt to override a final method, property, or subscript in a subclass is reported as a compile-time error. Methods, properties, or subscripts that you add to a class in an extension can also be marked as final within the extension’s definition.
You can mark an entire class as final by writing the final modifier before the class keyword in its class definition (final class). Any attempt to subclass a final class is reported as a compile-time error.

final修饰符加载属性、方法或者下标前面可以防止它被重写。尝试去重写被final修饰的属性、方法或者下标会得到一个编译时的错误。在extension中被final标记的也是一样。你也可以在一个类前面加上这个修饰符,这样其他类就不能继承此类。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,279评论 0 10
  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的阅读 13,430评论 5 6
  • 桃之夭夭,灼灼其华。之子于归,宜其家室。 夏圆是一个可爱的女孩,她生长在一个平凡的家庭。她虽然很好学,但是在那个贫...
    水曦蕊阅读 306评论 0 1