何时在Swift中使用协议

DEA*_*EEF 8 cocoa swift swift-protocols

我今天问了一个问题,因为我今天有点失落.它是关于Swift和协议以及有关面向协议编程(POP)的更多信息.

我读过有关它的文章,甚至是一本书,但我仍然感到困惑.每个人似乎都说协议是一个很好的工具等等,但我真的不了解它的力量.

我有一个问题,因为我正在编写一个类Volume,它是一个卷作为对象的表示.让我们说吧

struct Volume {
  var value: Float = 1
  var isLogScale: Bool = false
  var maxLogVolume: Float = 6.0 // value in dB
  var maxLinearVolume: Float = 1.0
  let dynamicRange: Float = 50.0


  func convertLinearToLog() -> Float {
    // Do some maths
  }

  func otherFunction() {
    print("Hello, I'm the most useless function in the world.")
  }
}
Run Code Online (Sandbox Code Playgroud)

这是一个典型的类没什么特别的.

但是......我应该更好地使用这样的协议:

protocol VolumeProtocol {
  var value: Float {get set}
  var isLogScale: Bool {get set}
  var maxLogVolume: Float {get set}
  var maxLinearVolume: Float {get set}
  let dynamicRange: Float {get}

  func convertLinearToLog() -> Float
  func otherFunction()
}
Run Code Online (Sandbox Code Playgroud)

然后重新实现一切

struct MyVolumeClass: VolumeProtocol {
// Same thing as before
}
Run Code Online (Sandbox Code Playgroud)

我真的无法回答这个问题,所以如果你能帮我什么时候使用协议,什么时候不能,我会很感激.

mat*_*att 7

协议有多个用例,但请这样考虑:

  • 对于类,协议提供了与类层次结构分开的轻量级继承层次结构。给定“动物”类及其子类“猫”,“狗”,“鸟”和“昆虫”,您如何指定仅“鸟”和“昆虫”共享该fly方法?

  • 对于结构,协议提供了一个继承层次结构,否则它将完全丢失!结构没有上层结构。那么,给定一个结构鸟和一个结构昆虫,您将如何指定它们共享一个fly方法?

现在,您可以回答“鸟类与昆虫”恰好有fly方法,到此结束。但是,当您需要说集合“具有fly方法的所有类型”时,这样做就不会做。而且你需要当你想编译器能够将发送给讲的是一套fly方法,对象,理由是它一个fly方法。

解决方案是一个协议:

protocol Flier {
    func fly()
}
Run Code Online (Sandbox Code Playgroud)

现在,传单是一种类型。可以在符合Flier的情况下使用符合Flier的任何类型的实例,并且编译器将让您将Flier告知fly,从而解决了问题:

var myFlier : Flier = Bird() // if Bird conforms to Flier
myFlier.fly() // legal
Run Code Online (Sandbox Code Playgroud)