很短的 文章 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
更加通用