了解具有泛型约束的泛型

时间:2019-02-27 08:06:50

标签: ios swift generics

protocol Nameable: Equatable {
    var name: String { get set }
}

struct Person: Nameable {
    var name: String
}

struct Car: Nameable {
    var name: String
}

现在我可以将一个函数约束为能够打印符合Nameable协议的元素,因为它们是同一类型?

func printNameable<T: Nameable>(_ list: [T]) {

}

但是如何创建此列表?我收到语法错误。

var nameableList<T: Nameable>: [T] = []

或者,如果我下一次尝试,我会得到协议“可命名”只能用作通用约束 ...

var nameables: [Nameable] = []

我被迫指定“可命名”类型(例如“人”或“汽车”)来创建此列表?

基本上,最后,我想要一个通用协议的数组,该数组可以具有我可以比较的各种不同类型的对象,如果它们的类型不同,则它们是不同的,但是如果不,我想比较一下。

var nameables: [Nameable] = [Person(name: "John"), Car(name: "Ferrari")]

nameables.contains(Car(name: "Ferrari")) 

(我想 Person Car 这两种类型都应符合Equatable协议)。

1 个答案:

答案 0 :(得分:1)

您实际上不能传递printNameable<T>(_:)包含CarPerson对象的数组,它只能包含一个或另一个。泛型类型T不是运行时值,它是在编译时计算的,因此,如果您的代码调用printNameable(persons)printNameable(cars),则实际上您将拥有2个不同的编译函数(如果有的话,请纠正我)我错了。

正如@Sandeep Bhandari在其评论中所述,由于您的协议扩展了Equatable(其中包含Self),因此您的协议只能用作通用约束。如果您希望您的协议以您想要的方式可用,则只需删除Equatable,然后将printNameable(_:)更改为

func printNameable(_ list: [Nameable]) {
}