泛型
泛型
1.泛型函数
func swapTwoValues < T >( inout a : T , inout b : T ){
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoValues (& someInt , & anotherInt )
var someString = "hello"
var anotherString = "world"
swapTwoValues (& someString , & anotherString )
2.泛型类型
struct Stack < T > {
var items = [ T ]()
mutating func push ( item : T ){
items . append ( item )
}
mutating func pop () -> T {
return items . removeLast ()
}
}
var stackOfString = Stack < String >()
stackOfString . push ( "uno" )
stackOfString . push ( "dos" )
3.类型约束语法
// T 必须是SomeClass的子类,U必须遵循SomeProtocol协议
func someFunction < T : SomeClass , U : SomeProtocol >( someT : T , someU : U ) {
// function body goes here
}
4.typealias和泛型接口
typealias为已经存在的类型重新定义名字,通过命名,可以让代码变得更便于理解。使用typealias关键字像使用普通的赋值语句一样,可以将某个已经存在的类型赋值为新的名字。
typealias Location = CGPoint
typealias Distance = Double
func distanceBetweenPoint ( location : Location , toLocation : Location )-> Distance {
let dx = Distance ( location . x - toLocation . x )
let dy = Distance ( location . y - toLocation . y )
return sqrt ( dx * dx + dy * dy )
}
let origin : Location = Location ( x : 0 , y : 0 )
let point : Location = Location ( x : 1 , y : 1 )
let distance : Distance = distanceBetweenPoint ( origin , point )
typealias是单一的,必须指定将某个特定的类型通过typealias赋值为新名字,而不能将整个泛型类型进行重命名。下面这样的命名都无法通过编译。
class Person < T > {}
typealias Worker = Person
typealias Worker = Person < T >
typealias Worker < T > = Person < T >
一旦泛型类型的确定性得到保证后,我们就可以重命名了。
typealias Worker = Person < String >
Swift中没有泛型接口,但是使用typealias,我们可以在接口里定义一个必须实现的别名。
protocol Container {
typealias ItemType
mutating func append ( item : ItemType )
var count : Int { get }
subscript ( i : Int ) -> ItemType { get }
}
InStack遵循Container协议。
struct IntStack : Container {
var items = [ Int ]()
mutating func push ( item : Int ){
items . append ( item )
}
mutating func pop () -> Int {
return items . removeLast ()
}
//遵循Container协议实现
typealias ItemType = Int
mutating func append ( item : ItemType ) {
self . push ( item )
}
var count : Int {
return items . count
}
subscript ( i : Int ) -> Int {
return items [ i ]
}
}
由于IntStack遵循Container协议的所有要求,只要通过简单的查找append方法的item参数类型和下标返回的类型,Swift就可以推断出合适的ItemType来使用,所以可以删除上面的typealias ItemTyp=Int这一行。
遵循Container协议的泛型Stack类型。
struct Stack < T >: Container {
// original Stack<T> implementation
var items = [ T ]()
mutating func push ( item : T ) {
items . append ( item )
}
mutating func pop () -> T {
return items . removeLast ()
}
// conformance to the Container protocol
mutating func append ( item : T ) {
self . push ( item )
}
var count : Int {
return items . count
}
subscript ( i : Int ) -> T {
return items [ i ]
}
}
// 多态?????
September 28, 2026
March 29, 2015
GitHub