Introducing Protocol-Oriented Programming in Swift 3

link
协议的扩展,可以根据实现这个协议的对象的实际情况(有无实现其他协议)来设置协议的默认值。:

protocol Bird {
 var name: String { get } 
 var canFly: Bool { get }
} 

protocol Flyable { 
var airspeedVelocity: Double { get }
}

extension Bird {
 // Flyable birds can fly!
 var canFly: Bool {
 return self is Flyable
 }
}

为什么不用基类

protocol extensions do not introduce any additional state.
也就是说协议扩展不能添加新的变量???


protocol Bird {
    var name: String { get }
    var canFly: Bool { get }
}

extension Bird {
    // Flyable birds can fly!
    var test: String {
        return "heheda"
    }
    var canFly: Bool {
        return true
    }
}

struct bigBird: Bird{
    var name: String {
        return "big bird"
    }
}

let a = bigBird()
print(a.name)
print(a.test)
print(a.canFly)

big bird
heheda
true

发现能在扩展中添加变量呀。没有引入其他的状态怎么理解?

???

当然protocol相比基类,应用范围广:结构体,枚举,都能用。

修改对象中协议的默认实现。 ---> 对这个对象进行extension:

extension UnladenSwallow {
     var canFly: Bool { 
     return self != .unknown 
 }
}

给实现了协议的部分对象添加新的方法

extension CustomStringConvertible where Self: Bird { 
    var description: String { 
    return canFly ? "I can fly" : "Guess I’ll just sit here :[" 
  }
}

在swift 标准库里发挥效用

让类型稍有不同的对象(通常这些对象关系和密切,是可以互相转化的) 拥有相同的方法。

协议能让不同的对象具有相同的可比较的属相。

比如汽车,鸟类都有移动速度这个共同属相。
可以用这用的方法来求取得这些不同对象的共同属性的比较结果:

func topSpeed(of racers: [Racer]) -> Double {
  return racers.max(by: { $0.speed < $1.speed })?.speed ?? 0
}
topSpeed(of: racers) // 3000

这里的局限是针对的是实现了Racer协议的数组,更加一般的形式是,实现了Racer协议的 Sequence 类型对象。所有用到泛型来定义:

func topSpeed(of racers: RacerType) -> Double
    where RacerType.Iterator.Element == Racer {
  return racers.max(by: { $0.speed < $1.speed })?.speed ?? 0
}

主要到这个套路:
规定sequence 中元素的类型

RacerType.Iterator.Element == Racer

更进一步的优化:

extension Sequence where Iterator.Element == Racer {
  func topSpeed() -> Double {
    return self.max(by: { $0.speed < $1.speed })?.speed ?? 0
  }
}
 
racers.topSpeed()        // 3000
racers[1...3].topSpeed() // 42

总结一下演进过程

  • 构造针对具有相同属性的对象{数组形式}的处理函数

参数:[协议]

  • 将函数的接受对象的范围从数组形式到sequence形式。

泛型:sequence协议 {指出 满足sequence 的泛型 ,他其中的元素 满足协议 (你要操作的属性)}

  • 直接将这个协议(定义共同通属性) 放入sequence 的协议扩展中。

刚刚做的是对一组具有相同属性的不同对象之间的比较,那如果是在同类对象之间的比较呢?

protocol Score: Equatable, Comparable {
  var value: Int { get }
}
 
struct RacingScore: Score {
  let value: Int
 
  static func ==(lhs: RacingScore, rhs: RacingScore) -> Bool {
    return lhs.value == rhs.value
  }
 
  static func <(lhs: RacingScore, rhs: RacingScore) -> Bool {
    return lhs.value < rhs.value
  }
}

你可能感兴趣的:(Introducing Protocol-Oriented Programming in Swift 3)