在Swift中何时使用带约束的关联类型?

在Swift中何时使用带约束的关联类型?,swift,protocols,Swift,Protocols,案例1和案例2的区别是什么。根据我的理解,案例1说,items是一个实现Item协议的任何类型的数组,案例2说的是协议本身不能被启动的事情。因此案例中的items也是一个实现Item协议的对象数组 根据我的理解,案例1说,items是一个实现Item协议的任何类型的数组,案例2说的是协议本身不能被启动的事情。因此案例中的items也是一个实现Item协议的对象数组 让我们为您的协议提供更好的名称,以演示这两种情况的不同之处。让我们将SomeProtocol重命名为ItemStorage。另外,假

案例1和案例2的区别是什么。根据我的理解,案例1说,items是一个实现Item协议的任何类型的数组,案例2说的是协议本身不能被启动的事情。因此案例中的items也是一个实现Item协议的对象数组

根据我的理解,案例1说,items是一个实现Item协议的任何类型的数组,案例2说的是协议本身不能被启动的事情。因此案例中的items也是一个实现Item协议的对象数组

让我们为您的协议提供更好的名称,以演示这两种情况的不同之处。让我们将
SomeProtocol
重命名为
ItemStorage
。另外,假设有两个类符合
Item
FooItem
BarItem

现在,我想创建两个实现
ItemStorage
的类,分别称为
FooItemStorage
BarItemStorage
。我希望它们只能存储各自类型的
。如果这是案例1,我可以很容易地做到:

    protocol Item {
      init(name: String)
    }

   //case1
    protocol SomeProtocol {
        associatedtype ItemType: Item
        var items: [ItemType] { get set }
    }

    //case2
    protocol SomeProtocol {
          var items: [Item] { get set }
    }
但是,在案例2中,数组的类型必须是
[Item]
,因此上述代码无法编译。我必须这样做:

class FooItemStorage: ItemStorage {
    typealias ItemType = FooItem
    var items: [FooItem] = []

    ...
}

class BarItemStorage: ItemStorage {
    typealias ItemType = BarItem
    var items: [BarItem] = []

    ...
}
我必须声明一个名为
myItems
的额外属性,该属性具有我所需的
[FooItem]
类型,并将
项的getter和setter委托给
myItems
。另外,从客户机代码的角度来看,
FooItemStorage
现在似乎可以存储任何类型的项目


注意,这并不是说具有关联类型的协议总是更好。具有关联类型的协议不能用作变量的类型。因此,如果您不需要符合性类需要不同类型的
FooItemStorage
BarItemStorage
之类的东西,并且您希望使用协议作为变量的类型,则不应使用关联的类型。

您的两种情况是不相关的。比较它们有什么意义?不清楚问题是什么。也许你不明白案例1是怎么说的?“但是,如果我们在协议中用associatedType定义类型本身”,案例1并不是这样做的。另外,请显示项的声明。这是什么?这是一个协议。我感到困惑,并认为ItemType的类型在案例1中声明为Item,但现在我明白了ItemType可以是实现Item protocol.Correct的任何类型。如果您现在理解了,请删除问题。修改问题以进行澄清。
class FooItemStorage: ItemStorage {
    typealias ItemType = FooItem
    var items: [Item] {
        get { return myItems }
        set {
            myItems = newValue as? [FooItem] ?? myItems
        }
    }
    var myItems: [FooItem] = []
    ...
}