
image.png
那我们应该怎样去处理呢?
由于所有的整数都遵守BinaryInteger协议,所有我们可以:
□ 第一种方法,使用泛型,并限定泛型
func isOdd<T: BinaryInteger>(_ i: T) -> Bool {
(i % 2) != 0
}
□ 给BinaryInteger协议添加扩展,这种方式是比较好的
extension BinaryInteger {
func isOdd() -> Bool {
(self % 2) != 0
}
}
print(3.isOdd())
/*输出结果*/
true
- 扩展可以给协议提供默认实现,也间接实现可选协议的效果
- 扩展可以给协议补充协议中从未声明过的方法
protocol MyProtocol {
func fun1()
}
extension MyProtocol {
func fun1() {
print("MyProtocol fun1")
}
func fun2() {
print("MyProtocol fun2")
}
}
我们都知道,只要遵守了协议,就必须实现协议中声明的方法;但是我们可以在协议的扩展中提供默认实现,这样就可以实现可选协议:
class Person: MyProtocol {}
var p = Person()
p.fun1() // MyProtocol fun1
p.fun2() // MyProtocol fun2
当然,如果我们再类里面去实现协议的方法,那么执行的还就执行类里面的实现:
class Person: MyProtocol {
func fun1() {
print("Person fun1")
}
func fun2() {
print("Person fun2")
}
}
var p = Person()
p.fun1() // Person fun1
p.fun2() // Person fun2
这里有一个
要注意一下:如下,
p声明为遵守MyProtocol协议类型,实际是Person;但是在调用方法的时候,没有在MyProtocol协议中声明但是在扩展中有默认实现的方法,对象p去调用的话,会执行协议扩展中的默认方法。
var p: MyProtocol = Person()
p.fun1() // Person fun1
p.fun2() // MyProtocol fun2
这是因为,fun2在协议中没有声明,那么编译器就不确定遵守它的类是否有实现该方法,所有优先执行协议扩展中实现的默认方法。
如果var p = Person(),这样写,并没有告诉编译器是遵守MyProtocol协议的对象,只是告诉编译器是Person对象,所以优先执行Person里面的方法。
泛型
class Stack<E> {
var elements = [E]()
func push(_ element: E) {
elements.append(element)
}
func pop() -> E {
elements.removeLast()
}
func size() -> Int {
elements.count
}
}
// 扩展中依然可以使用原类型中的泛型类型
extension Stack {
func top() -> E {
elements.last!
}
}
// 符合条件才扩展
extension Stack : Equatable where E : Equatable {
static func == (left: Stack, right: Stack) -> Bool {
left.elements == right.elements
}
}
文章均来自互联网如有不妥请联系作者删除QQ:314111741 地址:http://www.mqs.net/post/13578.html
添加新评论