转载

在 Swift 中使用 Protocol 作为函数参数

很短的 文章 TL;DR 作者完全就是在卖萌

有一些事情在 Python 中很简单:

class Person:       def __init__(self, name):         self.name = name  def changeName(named, newName):       named.name = newName  nick = Person('Nicholas')   nick.name # => 'Nicolas'  changeName(nick, 'Nicole')   nick.name # => 'Nicole'   

同样 Ruby 中也非常简单:

class Person     attr_accessor :name   def initialize(name)     @name = name   end end  def changeName(named, newName)     named.name = newName end  nick = Person.new('Nicholas')   nick.name # => "Nicholas"  changeName(nick, 'Nicole')   nick.name # => "Nicole"   

但在 Swift 中实现起来并不简单,所幸对于类(class)我们还有协议(protocol)

  • 声明一个只能由类继承的协议
  • 使用协议作为函数的参数类型
protocol Named: class {       var name: String { get set } }  class Person: Named {       var name: String      init(name: String) {         self.name = name     } }  func changeName(named: Named, newName: String) {       named.name = newName }  let nick = Person(name: "nick")   changeName(nick, "NICK")   println(nick.name) // "NICK"   

如果不想仅限于类,让 changeName 函数同样适用于结构体,可以这样做:

  • 声明一个泛型函数,使用类型 T 遵循协议 Named
  • 参数 T 必须是一个 inout 参数,用于之后能被修改(因为结构体是值传递)
  • 所有的参数必须是 var 不能是 let
protocol Named: class {       var name: String { get set } }  class Person: Named {       var name: String      init(name: String) {         self.name = name     } }  struct Pet: Named {       var name: String }  func changeName<T: Named>(inout named: T, toName newName: String) {       named.name = newName }  var nick = Person(name: "nick")   changeName(nick, "NICK")   println(nick.name) // "NICK"  var maru = Pet(name: "Maru")   changeName(maru, "Hana")   println(maru.name) // "Hana"   

就这样,我们没有使用继承,也能够让 changeName 更加通用

-EOF-
原文  http://chengway.in/zai-swift-zhong-shi-yong-protocol-zuo-wei-han-shu-can-shu-duan-wen/
正文到此结束
Loading...