Swift 学习笔记 - 04

来源:互联网 发布:mt4交易软件 编辑:程序博客网 时间:2024/05/22 04:31

1.Generics

1.Generic Functions

           func swapTwoValues<T>(inout a:T, inout _ b: T) {

               let temporaryA = a

                a = b

                b = temporaryA

            }

2.Generic Types

1.使用例子:

           struct Stack<Element> {

               var items = [Element]()

               mutating func push(item:Element) {

                   items.append(item)

                }

               mutating func pop() ->Element {

                   return items.removeLast()

                }

            }

2.Extending a Generic Type 当用Extension扩展一个泛型类型的时候,不需要再写 Generic Parameter List了,直接用源Type的泛型参数就可以了

           extension Stack {

               var topItem: Element? {

                   return items.isEmpty ? nil : items[items.count - 1]

                }

            }

3.可以给Generic Parameter List添加约束.

1.使用方法

               func someFunction<T: SomeClass, U: SomeProtocol>(someT:T, someU: U) {


                }

2.有什么用途?

1.比如Dictionary中,key的值必须是Hashable.若key没有遵守Hashable协议,那对于Dictionary来说 根本没法计算key的哈希值,也就根本无法正常工作了

2.比如要判断2个元素是否相等. 在Swift 要使用  == 或 != 来判断两个元素是否相等的话,这两个元素必须实现Equatable. 如果没有显示地给泛型参数一个Equatable协议约束,这两个元素根本无法比较,编译都无法通过  (从这点可以看出,Swift的泛型并不完全像C++一样,C++是编译调用代码的时候直接将泛型参数给替换了,所以显得非常的灵活,但是也相对的不是很安全)

4.(非泛型内容) 可以给Protocol添加一个Associated Types 来实现类似于 泛型的功能

使用方法:

               protocol Container {

                   typealias ItemType

                   mutating func append(item:ItemType)

                   var count: Int {get }

                   subscript(i: Int) ->ItemType { get }

                }

               struct ArrayList: Container {

                   var items = [Int]()

                    // conformance to the Container protocol

                   typealias ItemType = Int //由于Swift的推断机制,这句话其实可以省略

                   mutating func append(item:Int) {

                       self.items.append(item)

                    }

                   var count: Int {

                       return items.count

                    }

                   subscript(i: Int) ->Int {

                       return items[i]

                    }

                }

补充1:还可以加上泛型参数,然后把所有Int换成那个泛型参数即可

补充2:由于系统自带的Array已经实现了这几个功能,所以直接扩展(extension)Array 让Array遵守Container协议即可,多余的代码不用写.

5.Where Clauses

           func allItemsMatch<

               C1: Container, C2: Container

               where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>//ItemType是在Container中声明的

                (someContainer:C1, anotherContainer: C2) -> Bool{

               //TODO

            }

2.Access Control (访问控制)

1.Swift提供了三种访问权限 (为了简洁,下面用实体来代替properties, types, functions等等)

1.Public access : 修饰的实体 既可以在 自己模块内的任何源代码文件中访问,也可以在 其他导入自己模块的源代码中访问.最好当说明接口的时候使用这个权限

2.Internal access: 修饰的实体 可以在 自己模块内的任何源代码文件中访问,但是不能在 其他导入自己模块的源代码中访问.最好当定义模块内的内部结构体的时候使用这个权限

3.Private access:修饰的实体 只能在定义自己的源代码文件中访问.最好当想隐藏一个功能的特定片段的实现细节的时候使用这个权限.

注意:在Swift中,private不同于Java中的private.  Swift的private的范围是整个源代码文件.

2.Swift中Access Level遵守一个综合的规定准则: 实体不能定义在另一个比它访问等级更低的实体中.比如:

1.一个public变量不能定义在一个internal/private的type中

2.一个function不能比它的参数/返回值的访问等级高

3.如果不设置访问等级,那么默认的访问等级是  internal access.

4.type的访问等级会影响type内部的成员的默认访问等级:

1.type是private,那么type内部的成员的默认访问等级是private

2.type是internal/public,那么type内部的成员的默认访问等级是internal

5.Tuple types的访问等级来自它里面的成员,取成员里面最小的访问等级作为自己的访问等级(不能显式声明,只能被推断出)

6.Function Types的访问等级 取形参和返回值中最小的访问等级作为自己的访问等级 (可以显式声明,但是有效无效要看情况)

7.Enumeration Types内部各个的访问等级和 enum 声明的访问等级相同

8.Raw Values 和 Associated Values 的访问等级必须不小于enumeration

9.subclass的访问等级不能比superclass的大.但是重写的方法/属性 的访问等级可以比原来的大(仔细想想就知道为什么了,没有小的必要啊). 就算原来的方法的访问等级是private 只要这个调用发生在同一源文件,子类的成员也能调用原方法.(这个的原因其实就是简单的访问等级的作用范围 看2.1)

10.getter 和 setter . 

1.setter的访问等级可以比getter的低.  

2.声明方式 (不管是 computed property 还是 stored property 都是这样)

publicprivate(set) var a: NSString 

11.initializer的访问等级

1.一般的自定义initializers的访问等级小于等于type.但是有一个例外,那就是required initializer(注意:只有class才有required initializer).required initializer的访问等级必须和class的访问等级相同

2.和函数相同,构造方法的参数的访问等级不能小于构造方法的访问等级

3.Default Memberwise Initializers . 如果结构体中有任何一个stored property是private的,那么Memberwise Initializers的访问等级也是private,除此以外,Memberwise Initializers的访问等级都是internal

12.Protocol的访问等级:

1.Protocol里面声明的所有内容的访问等级永远和Protocol的访问等级相同.

2.如果有一个Protocol继承自另外一个Protocol,那么这个Protocol的访问等级不能大于父Protocol.

3.遵守该Protocol的type对于Protocol的实现 的访问等级至少拥有protocol的访问等级.

13.Extension

1.Extension中新声明的功能 默认地和源type的访问等级类似(如果源type是public/internal,那么它们访问等级是internal,如果源是private,那么它们也是private).

2.你可以显式地声明Extension内功能的访问等级(只能小不能大).也可以显式地声明Extension的访问等级(只能小不能大),这个访问等级作为Extension内功能默认的访问等级,当然这个功能的默认访问等级还能够被显式声明为更低的访问等级

3.如果你用extension将一个已存在的type遵守一个新的协议,那么你不能显式地声明这个extension.相反,这个默认地访问等级是来自于protocol

3.不同于C,在Swift中,默认情况下算术操作如果溢出Swift会出错.如果想进行溢出运算 必须使用 溢出操作(&+等).所有的溢出操作都必须以&开头

4.Swift可以重载基本的操作符用于structure,enumeration,class的运算.





























0 0