Swift 协议

什么是协议?

在 Swift 中,协议是一种定义期望的属性、方法、下标和构造器等要求的蓝图。它类似于其他编程语言中的接口,但提供了更多的灵活性。通过使用协议,你可以确保任何遵循该协议的类型都具备某些特定的功能或行为。

定义协议

协议的定义使用 protocol 关键字,后跟协议名称。在大括号 {} 内可以定义协议的要求。

上面的代码定义了一个名为 Identifiable 的协议,它要求任何遵循此协议的类型必须有一个可读写的 id 属性,其类型为 String

实现协议

实现协议意味着一个类型需要满足协议所定义的所有要求。可以通过扩展类型或在类、结构体或枚举的定义中实现协议来完成。

在这个例子中,User 结构体遵循了 Identifiable 协议,并实现了 id 属性。

多个协议的实现

一个类型可以遵循多个协议。这可以通过在类型定义时列出所有遵循的协议来实现。

-- -------------------- ---- -------
-------- ------- -
    ---- ---------------- -- ---
-

-------- ------------- -
    ---- -------
-

-------- ----------- -
    ---- ------------------ ----
-

----- --------- -------- -------------- ----------- -
    ---- ---------------- -- --- -
        ------ -----
    -

    ---- ------- -
        --------------------
    -

    ---- ------------------ ---- -
        ------------- - -------- --- ------- -------
    -
-

--- -------- - ----------
-------------------------
----------------
--------------------------- --

在这个例子中,Employee 类同时实现了 PayableNeedsTrainingHasVacation 三个协议。每个协议都定义了不同的功能,Employee 类分别实现了这些功能。

协议作为类型

协议本身可以被用作类型。这意味着它们可以用于函数参数、返回值、变量和常量的类型声明。

在这个例子中,printID 函数接受任何遵循 Identifiable 协议的类型的实例作为参数。这展示了如何将协议用作类型。

协议继承

一个协议可以继承自另一个或多个协议,从而组合它们的要求。这使得协议能够更具体地定义一组要求。

-- -------------------- ---- -------
-------- ----------------- --------- ------------ -
    ---- ----------------- ----
-

----- -------- ---------------- -
    --- --- ------
    
    -------- ------- -
        ------- - --
    -
    
    ---- ---------------- -- --- -
        ------ -----
    -
    
    ---- ------- -
        -------------- ------------
    -
    
    ---- ------------------ ---- -
        -------------- ----- - -------- --- ------- -------
    -
    
    ---- ----------------- ---- -
        ------------- ----- -- ------------
    -
-

--- ------- - ----------- ------
------------------------- -----

在这个例子中,AdvancedEmployee 协议继承自 EmployeeIdentifiable 协议,要求任何遵循它的类型不仅要实现这两个协议的所有要求,还要实现 giveBonus 方法。

类专属协议

有时,你可能希望限制协议只能被类类型遵循,而不能被结构体或枚举类型遵循。这可以通过使用 class 关键字来实现。

-- -------------------- ---- -------
-------- ---------------------- ------ ------------ -
    -- ----
-

----- ---------- --------------------- -
    --- --- ------
    -------- ------- -
        ------- - --
    -
-

-- -----------------------
-- ------ ----------- --------------------- -
--     --- --- ------
-- -

通过这种方式,可以确保协议的实现仅限于类类型,从而控制实现者的类型。

协议组合

在某些情况下,你可能希望一个类型同时遵循多个协议。这时可以使用协议组合,通过在类型定义时使用 & 符号来组合多个协议。

在这个例子中,someFunction 函数接受一个同时遵循 IdentifiablePayable 协议的类型的实例作为参数。

协议中的默认实现

Swift 允许在协议中提供默认实现。这样,遵循该协议的类型可以选择性地重写这些实现。

-- -------------------- ---- -------
-------- ---------- -
    --- --------- ------ - --- -
    ---- ---------- -- ------
-

--------- ---------- -
    ---- ---------- -- ------ -
        ------ ------- -- ---- -- ------------
    -
-

------ ------- ---------- -
    --- --------- ------
-

--- ---- - ---------------- ----- -----------
---------------------- -- --------- -- ---- -- ---- ---------

在这个例子中,FullyNamed 协议定义了一个 sayHello 方法,其默认实现返回一个问候语。Person 结构体遵循 FullyNamed 协议并实现了 fullName 属性。当调用 sayHello 方法时,它将使用协议提供的默认实现。

协议的静态类型

在 Swift 中,协议也可以具有静态类型。这意味着你可以定义一个方法或属性,其类型为协议。

-- -------------------- ---- -------
-------- --------------------- -
    ---- -------- -- ------
-

----- ---------------------------- --------------------- -
    ------------ --- ---------- - ----
    --- - - --------
    --- - - ------
    --- - - -------

    ---- -------- -- ------ -
        ---------- - ------------ - - - ---------------------------------- ---
        ------ ---------- - -
    -
-

--- --------- - -----------------------------
------------- - ------ ------- -----------------------
-- --------- - ------ ------- -----------

-- ------
---- ------------------- ------------------------ ---------- -- -
    -------------------------
-

---------------------------

在这个例子中,LinearCongruentialGenerator 类遵循 RandomNumberGenerator 协议,并实现了 random 方法。printRandomValue 函数接受任何遵循 RandomNumberGenerator 协议的类型的实例作为参数,展示了如何使用协议类型。

协议中的关联类型

关联类型允许你在协议中引用未知的类型,并在遵循协议的类型中指定具体的类型。

-- -------------------- ---- -------
-------- --------- -
    -------------- ----
    -------- ---- -------- ----- -----
    --- ------ --- - --- -
    ------------ ---- -- ---- - --- -
-

------ --------- --------- -
    -- ---------
    ------- --- ----- - -------
    -- ------------------
    -------- ---- -------- ----- ---- -
        ------------------
    -
    --- ------ --- -
        ------ -----------
    -
    ------------ ---- -- --- -
        ------ --------
    -
-

--- ----------- - ----------
----------------------
----------------------
----------------------
--------------------- -- -----

在这个例子中,Container 协议定义了一个关联类型 Item,表示容器中存储的元素类型。IntStack 结构体遵循 Container 协议,并指定了 Item 类型为 Int

总结

协议是 Swift 中一种强大的工具,用于定义一组要求,这些要求可以被多个类型遵循。通过使用协议,你可以创建更灵活和可复用的代码。从定义协议到实现协议、使用协议作为类型、以及使用协议组合和关联类型,Swift 提供了许多机制来增强你的编程能力。

以上是关于 Swift 协议的详细教程。希望这些内容能帮助你更好地理解和使用协议。

上一篇: Swift 扩展
下一篇: Swift 泛型
纠错
反馈