# Swift进阶之泛型

swift-generic.jpg

## 1. 写一个泛型函数

``````

func addInts(x: Int, y: Int) -> Int {
return x + y
}

let intSum = addInts(x: 1, y: 2)
print(intSum)

func addDoubles(x: Double, y: Double) -> Double {
return x + y
}

func add1<T>(x: T, y: T) {
return x + y
}

``````

## 2. 标准库中的泛型引用

``````let numbers = [1, 2, 3]
let firstNumber = numbers[0]

var numbersAagin: Array<Int> = []
numbersAagin.append(1)
numbersAagin.append(2)
numbersAagin.append(3)

let countryCodes = ["Arendelle": "AR", "Genovia":"GN", "Freedonia": "FD"]
let countryCode = countryCodes["Freedonia"]

let optionalName = Optional<String>.some("Princess Moana")
if let name = optionalName {
print(name)
}

``````

## 3. 泛型类型

``````
struct Queue<Element> {
fileprivate var elements: [Element] = []
mutating func enqueue(newElement: Element) {
elements.append(newElement)
}

mutating func dequeue() -> Element? {
guard !elements.isEmpty else { return nil }
return elements.remove(at: 0)
}
}

var q = Queue<Int>()
q.enqueue(newElement: 4)
q.enqueue(newElement: 2)

print(q.dequeue())
print(q.dequeue())
print(q.dequeue())

``````

``````struct SquareMatrix<T> {
var backingArray: [T] = []
let size: Int
func itemAt(row: Int, column: Int) -> T {
return ...
}

init(size: Int, initial: T) {
self.size = size
backingArray = Array(repeating: initial, count: size * size)
}
}

let a = SquareMatrix(size: 10, initial: 50)
let b : SquareMatrix<String?> = SquareMatrix(size: 5, initial: nil)

``````

## 4. 泛型函数

``````
func pairs<Key, Value>(from dictionary: [Key: Value]) -> [(Key, Value)] {
return Array(dictionary)
}

let somePairs = pairs(from: ["mininum": 199, "maxinum": 299])
print(somePairs)

let morePairs = pairs(from: [1: "swift", 2: "Generics", 3: "Rule"])
print(morePairs)

``````

## 5. 泛型约束

``````
func middle<T: Comparable>(array: [T]) -> T? {
guard !array.isEmpty else { return nil }
return array.sorted()[(array.count-1) / 2]
}

middle(array: [2, 5, 1, 3, 4])

protocol Summable {
static func +(lhs: Self, rhs: Self) -> Self
}

extension Int: Summable {

}

extension Double: Summable {

}

func add2<T: Summable>(x: T, y: T) -> T {
return x + y
}

extension String: Summable {

}

``````

## 6. 扩展泛型类型

``````
extension Queue {
func peek() -> Element? {
return elements.first
}
}

``````

## 7. 继承泛型类型

``````
class Box<T> {

}

func wrap() {

}
}

class Rose {

}

override func wrap() {
print("wrap with love paper")
}
}

class Shoe {

}

class GlassSlipper: Shoe {

}

class ShoeBox: Box<Shoe> {

}

let box = Box<Rose>()
let shoeBox = ShoeBox()

let valentines = ValentinesBox()

``````

## 8. 泛型定义枚举的关联值

``````
enum Result<Value> {
case success(Value)
case failure(Error)
}

enum MathError: Error {
case divisionByZero
}

func divide(_ x: Int, by y: Int) -> Result<Int> {
guard y != 0 else { return .failure(MathError.divisionByZero) }
return .success(x / y)
}

``````

## 9. 在协议中使用关联类型associatedType作为泛型

``````
protocol Animal {
associatedtype Food
func eat(food: Food)
}

struct Cow: Animal {
typealias Food = String
func eat(food: Food) {
print("my food can be any string")
}
}

let cow = Cow()
cow.eat(food: "corn")

struct Chicken: Animal {
enum Food: String {
case grass, corn
}

func eat(food: Food) {
switch food {
case .grass:
print("My food is a grass enum")
case .corn:
print("my food is a corn enum")
}
}
}

let chicken = Chicken()
chicken.eat(food: .grass)

struct Dog: Animal {
typealias Food = [String]
func eat(food: Food) {
food.forEach { print("I am eating an array of food, current is \(\$0)") }
}
}

let dog = Dog()
dog.eat(food: ["cake", "treat", "bone"])

``````