简体   繁体   English

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

[英]What happens when a Class conforms to a protocol, which contains mutating function?

I was just experimenting with Protocol programming in Swift. 我只是在Swift中试验协议编程。 During this, I came across the following scenario. 在此期间,我遇到了以下情况。 Let's say we have a protocol like, 假设我们有一个类似的协议,

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

Now let's say I have a class called MyClass and it conforms to my SomeProtocol like, 现在假设我有一个名为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)
    }
}

Let's say I have another structure & another Protocol like, 假设我有另一个结构和另一个协议,比如

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
    }

}

So now my observations are, 所以现在我的意见是,

  1. For a class, it doesn't matter if the function is mentioned as mutating in the protocol and we are never allowed to mention methods in class as mutating. 对于一个类,如果函数在协议中被提及为变异并不重要,我们绝不允许在类中提及变异方法。
  2. For a struct, if the implemented method, doesn't modify members we need not mention func as mutating even tough in protocol it is mutating. 对于一个结构,如果实现的方法,不修改成员,我们不需要提到func作为变异甚至在协议中很难变异它是变异的。
  3. For a struct, if we implement protocol method as mutating func and if we don't specify the method as mutating func in the protocol. 对于结构,如果我们将协议方法实现为变异func,并且如果我们没有将该方法指定为协议中的变异func。 Compiler gives error. 编译器给出错误。

Currently I am confused with the way the compiler is behaving with the structures due to the above scenarios. 目前,由于上述情况,我对编译器对结构的行为方式感到困惑。 If someone could explain the significance of mutating functions inside a protocol ie "when we declare the func inside a protocol as a mutating, should we not make the func mutating when we implement it?" 如果有人可以解释在协议中改变函数的重要性,即“当我们将协议中的函数声明为变异时,我们是否应该在实现它时使func变异?” It'd be really great and helpful. 这真的很棒,乐于助人。

PS I know what mutating functions are, I am just confused with the mutating methods defined inside a protocol. PS我知道变异函数是什么,我只是对协议中定义的变异方法感到困惑。

Thanks in advance. 提前致谢。

I don't see what the "confusion" is. 我看不出“混乱”是什么。 You've elucidated the rules beautifully! 你已经精美地阐明了这些规则! A struct may implement a protocol's mutating function as nonmutating, but it may not implement a protocol's nonmutating function as mutating . 结构可以将协议的mutating函数实现为非mutating ,但它可能不会将协议的非mutating函数实现为mutating Once you've said those rules, there's nothing to be "confused" about. 一旦你说出这些规则,就没有什么可以“混淆”了。 The rules are the rules. 规则是规则。

Classes don't have mutating functions so your investigations there are sort of irrelevant. 类没有变异功能,所以你的调查有点无关紧要。 If you had declared your protocol as a class protocol, your mutating annotation in the protocol would have been illegal. 如果您已将协议声明为class协议,则协议中的mutating注释将是非法的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM