当一个类符合一个包含变异函数的协议时会发生啥?

Posted

技术标签:

【中文标题】当一个类符合一个包含变异函数的协议时会发生啥?【英文标题】:What happens when a Class conforms to a protocol, which contains mutating function?当一个类符合一个包含变异函数的协议时会发生什么? 【发布时间】:2016-04-29 13:00:38 【问题描述】:

我只是在 Swift 中试验协议编程。在此期间,我遇到了以下情况。 假设我们有一个类似的协议,

protocol SomeProtocol 
    .....
    mutating func mutatingFunc()
    .....

现在假设我有一个名为 MyClass 的类,它符合我的 SomeProtocol 之类的,

struct MyStruct 
    var width = 0, height = 0


extension MyStruct: SomeProtocol 

//1. If I remove the mutating keyword from following method definition, compiler will give me error, that's understandable as we are modifying structure members
//2. Also note that, if I remove the mutating keyword while defining protocol & keep mutating keyword in the below method, the compiler will say that structure doesn't conform to protocol

    mutating func mutatingMethod() 
        width += 10
        height += 10
    



class MyClass 
    var width = 10


extension MyClass: SomeProtocol 

//1. However while implementing the protocol method in class, I can implement the same protocol method, and the compiler doesn't complaint even if I don't mention mutating keyword. 
//2. But compiler will complain that mutating isn't valid on methods in classes or class-bound protocols, if I mention the mutating keyword
    func mutatingMethod() 
        width += 10
        print(width)
    

假设我有另一个结构和另一个协议,

protocol AnotherProtocol 
    func nonMutatingFunc()


struct MyAnotherStruct 
    var width = 0

extension MyAnotherStruct: SomeProtocol, AnotherProtocol 
    func mutatingFunc() 
//1. Compiler is happy even without the mutating keyword as we are not modifying structure members, also the structure conforms to SomeProtocol.
        print("Hello World")
    
    mutating func nonMutatingFunc() 
    //1. Compiler cries that we are not conforming to AnotherProtocol as the function is mutating
        width += 10
    


所以现在我的观察结果是,

    对于一个类,函数是否在协议中被提及为变异并不重要,我们绝不允许在类中提及方法为变异。 对于一个结构体,如果实现的方法不修改成员,我们就不需要提到 func 作为变异,即使在协议中它是变异的。 对于一个结构,如果我们将协议方法实现为变异函数,并且如果我们没有在协议中将方法指定为变异函数。编译器报错。

由于上述情况,目前我对编译器对结构的行为方式感到困惑。如果有人可以解释协议内变异函数的重要性,即“当我们将协议内的 func 声明为变异时,我们是否应该在实现时不让 func 变异?”这真的很棒而且很有帮助。

附:我知道变异函数是什么,我只是对协议中定义的变异方法感到困惑。

提前致谢。

【问题讨论】:

【参考方案1】:

我不明白“混乱”是什么。你已经很好地阐明了规则!结构可以将协议的mutating 函数实现为非变异,但它可能无法将协议的非变异函数实现为mutating。一旦你说出了这些规则,就没有什么可“混淆”的了。规矩就是规矩。

类没有变异函数,所以你在那里的调查有点无关紧要。如果您已将您的协议声明为 class 协议,那么您在协议中的 mutating 注释将是非法的。

【讨论】:

我的在线书(apeth.com/swiftBook/ch04.html#_declaring_a_protocol)会告诉你同样的事情:“如果协议缺少mutating,采纳者不能添加。但是,如果协议,采纳者可以省略mutating有。” 我的问题是,当您将协议中的 func 声明为 mutating 时,我们是否应该在实现时不让 func 发生变异?谢谢您的解释。行 - “如果协议缺少突变,采用者无法添加突变。但是,如果协议有突变,采用者可以省略突变。”消除了我的困惑。 感谢,感谢您的接受/支持,但相信我,您已经完美地解决了这个问题!你的侦探工作非常出色。你准确地表达了事实。真的没有更多要知道的了。 谢谢马特。我不知道 - “如果协议缺少变异,采用者无法添加变异。但是,如果协议有变异,采用者可能会省略变异。”我在任何文档中都没有遇到过。这就是为什么我很困惑。非常感谢您的回答:)

以上是关于当一个类符合一个包含变异函数的协议时会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

当删除没有虚拟析构函数的多态对象时会发生啥?

当返回对象的函数在没有返回语句的情况下结束时会发生啥

C alloca 函数 - 当试图分配太多内存时会发生啥

当调用winsock 中的recv 函数并且没有收到所有数据时会发生啥?

在 C 中通过引用传递时会发生啥?

当两个或多个哲学家检查互斥锁为 1 并同时关闭互斥锁并进入测试函数时会发生啥