Swift3.0学习笔记-Generics

https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html#//apple_ref/doc/uid/TP40014097-CH26-ID179


     Swift的Generics其实就是泛型, 而且语法和作用跟Java很像。 Swift的三种集合类型Set、Array和Dictionary都使用泛型声明成员参数类型, 跟Java的Set、List和Map类似。

附Swift的定义:

public struct Set<Element : Hashable> : SetAlgebra, Hashable, Collection, ExpressibleByArrayLiteral 
说明:Set是结构体,数据类型Element必须实现了Hashable接口。

public struct Array<Element> : RandomAccessCollection, MutableCollection 
说明:Array是结构体, 数据类型是泛型Element。


public struct Dictionary<Key : Hashable, Value> : Collection, ExpressibleByDictionaryLiteral 
说明:Dictionary是结构体, 2个参数都是泛型。第一个参数类型Key实现了Hashable接口, 第二个参数类型是Value。 这里的Key和Value都是数据类型。


苹果用了一个例子解释泛型的用处, 即交换2个参数的值(PS:如果懂得其它语法的泛型,这个例子可以跳过。)

1、交换2个整型变量的值,在以前博文中有该示例代码:

func swapTwoInts(_ a: inout Int, _ b: inout Int) {  //如果要修改值必须添加inout关键字,表示是引用
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)  //注意参数前添加&符号,表示引用
someInt等于107,anotherInt等于3


2、交换2个字符串类型的值:

func swapTwoStrings(_ a: inout String, _ b: inout String) {
    let temporaryA = a
    a = b
    b = temporaryA
}


3、交换2个浮点型类型的值:

func swapTwoDoubles(_ a: inout Double, _ b: inout Double) {
    let temporaryA = a
    a = b
    b = temporaryA
}

从上面3个示例代码可以看出只有函数参数类型不同, 函数体是一模一样的。  使用泛型的参数类型,一个函数就能实现交换2个值的功能。 跟Java一样, Swift泛型使用尖括号<T>。

func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
// someInt is now 107, and anotherInt is now 3
 
var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
// someString is now "world", and anotherString 
注意:参数一定添加&前缀,表示它是引用传递。

PS: Swift对泛型的命名没有限制, 由一个或若干个英文字符组成。 合法命名示例:<T>, <T, V>, <Element>, <AAA>, <TypeC>等等。


Swift同样支持protocol即接口使用泛型, 就像Java的interface使用泛型一样。使用associatedtype关键字作为泛型的前缀。示例代码如下:

    public interface ICallback<T> {
        int getCount(T param);
    }
上面是个最简单的Java接口类, 函数getCount的参数是泛型T。 

protocol ICallBack {
    associatedtype T    //assciatedtype表示T是一个泛型
    func getCount(_ param: T) -> Int
}
  上面是Swift的写法, 跟Java代码的功能完全一样。

泛型也支持用where关键字添加限制条件, 下面示例代码使用==判断泛型是否相同; 用法跟SQL有点像偷笑。 在调用allItemsMatch函数时必须保证参数类型符合where条件。

protocol Container {
    associatedtype ItemType
    mutating func append(_ item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}

func allItemsMatch<C1: Container, C2: Container>
    (_ someContainer: C1, _ anotherContainer: C2) -> Bool
    where C1.ItemType == C2.ItemType, C1.ItemType: Equatable {
        ...
}
1、泛型C1必须实现了Container, C2实现了Container。 
2、someContainer是C1类型的;

3、anotherContainer是C2类型的;

4、函数返回值是布尔类型的;

5、在函数返回值后面可以添加where判断语句,用于判断类型C1和C2的ItemType是否一样, 而且ItemType实现了Equatable。


 Swift的泛型语法跟Java泛型很像, 就不按照苹果原文翻译举例了。  总结一个Swift Generic的特性:

1、 基本语法是在类、结构体、枚举、函数名称后面跟着<>和字符串, 可以有一个或者多个数据类型;

2、泛型可以添加限制条件,即实现了几个接口Protocol;  语法是<T: Type>。

3、protocol在使用泛型时要添加成员变量, 并使用associated type关键字。

4、在函数里使用泛型时可以使用where关键字限制各个参数类型的关系。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值