protocol Item {
init(name: String)
}
//case1
protocol SomeProtocol {
associatedtype ItemType: Item
var items: [ItemType] { get set }
}
//case2
protocol SomeProtocol {
var items: [Item] { get set }
}
案例1和案例2有什么区别?据我的理解,案例1表示item是实现Item协议的任何类型的数组,而case 2则表示协议本身不能做同样的事情因此,item再次是一个实现Item协议的对象数组。
答案 0 :(得分:0)
根据我的理解,情况1表示项目是实现项目协议的任何类型的数组,情况2表示不能启动协议本身的同一件事,因此情况下的项目又是数组实现Item协议的对象。
让我们给您的协议起更好的名字,以证明这两种情况是如何不同的。让我们将SomeProtocol
重命名为ItemStorage
。另外,假设有两个符合Item
的类,FooItem
和BarItem
。
现在,我想创建两个实现ItemStorage
的类,分别称为FooItemStorage
和BarItemStorage
。我希望他们只能存储各自的Item
类型。如果是第一种情况,我可以很容易地做到这一点:
class FooItemStorage: ItemStorage {
typealias ItemType = FooItem
var items: [FooItem] = []
...
}
class BarItemStorage: ItemStorage {
typealias ItemType = BarItem
var items: [BarItem] = []
...
}
但是,在情况2中,数组必须为[Item]
类型,因此上面的代码将无法编译。我必须做这样的事情:
class FooItemStorage: ItemStorage {
typealias ItemType = FooItem
var items: [Item] {
get { return myItems }
set {
myItems = newValue as? [FooItem] ?? myItems
}
}
var myItems: [FooItem] = []
...
}
我必须声明一个名为myItems
的额外属性,该属性具有我想要的类型[FooItem]
,并将items
的getter和setter委托给myItems
。另外,从客户端代码的角度来看,似乎FooItemStorage
现在可以存储任何种类的项目。
请注意,这并不是说具有关联类型的协议总是更好。具有关联类型的协议不能用作变量的类型。因此,如果不需要FooItemStorage
和BarItemStorage
之类的符合类需要不同类型的东西,并且希望将协议用作变量的类型,则不应使用关联的类型。 / p>