协议和枚举中的Swift通用

  • 协议只能作为一个通用约束,因为它有 Self 或相关的类型要求。
  • 协议不允许使用通用参数,而使用关联类型。
  • 不能专攻非通用型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112


import Foundation

protocol BaseReq {
// Generic Type T in protocol
associatedtype T
func obj(_ s:String) -> T
init(completion:((_ res: Result<T>)->())?)
}

extension BaseReq {
func launch() {
let s = "network return string"
obj(s)
}
}

class AReq: BaseReq {
// declare the Type of T
typealias T = AObj
required init(completion:((_ res: Result<T>)->())?) {

}

func obj(_ s: String) -> T {
return T(s)
}
}

class BReq: BaseReq {
typealias T = BObj
required init(completion:((_ res: Result<T>)->())?) {

}

func obj(_ s:String) -> T {
return T(s)
}
}

class BaseObj {

}

class AObj: BaseObj {

var a = "a"

init(_ s: String) {
print("a", s)
}
}

class BObj: BaseObj {

var b = "b"

init(_ s: String) {
print("b", s)
}
}

class Launch {

// static func launch(req: BaseReq) -> BaseReq {
// 如果你像上面那样写,你会得到。
// 错误:协议'BaseReq'只能作为通用约束使用,因为它有Self或相关的类型要求。
static func launch<U: BaseReq>(req: U) -> U {
let s = "network return string"
print(req)

req.obj(s)

return req
}
}

// 不能对非通用类型进行特殊化
// enum Result {
enum Result<T> {
case suc(T)
case err(Error)
}


let areq = AReq { (r) in
switch r {
case .suc(let s):
//S is AObj, we can s.a
s.a
case .err(let r):
break
}
}
areq.launch()
// or
Launch.launch(req: areq)

let breq = BReq { (r) in
switch r {
case .suc(let s):
//S is BObj, we can s.b
s.b
case .err(let r):
break
}
}
breq.launch()
Launch.launch(req: breq)
s