2016-04-29 7 views
1

私はSwiftでプロトコルプログラミングを試していました。この間、私は次のシナリオに遭遇しました。 のような、クラスが突然変異関数を含むプロトコルに準拠するとどうなりますか?

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

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) 
    } 
} 

だが、私は別の構造&別のプロトコルなどを持っているとしましょう、のは、私はMyClassのというクラスを持っており、それはのように私のSomeProtocolに準拠しましょう我々はプロトコルを持っているとしましょう、

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 
    } 

} 

は、だから今、私の観察は、

です
  1. クラスでは、関数がプロトコルで突然変異として記述されているかどうかは関係ありません。クラス内のメソッドを突然変異として記述することは決してできません。
  2. 構造体の場合、実装されたメソッドがメンバを変更しない場合、funcはプロトタイプで突然変異していると言い換える必要はありません。
  3. structの場合、プロトコルメソッドをmutating funcとして実装し、プロトコルでmutating funcとしてメソッドを指定しない場合。コンパイラはエラーを出します。

現在のところ、私は、上記のシナリオのために、コンパイラが構造体で動作する方法と混同しています。誰かがプロトコル内の関数を変更することの意味を説明することができれば、「プロトコル内の関数を突然変異として宣言するとき、関数を実装するときにfuncを突然変異させてはいけませんか?それは本当に素晴らしいと助けになるだろう。

P.S.私は突然変異関数が何であるか知っています、私はちょうどプロトコルの中で定義された突然変異方法と混同しています。

ありがとうございます。

答えて

3

"混乱"が何であるかわかりません。あなたはルールを美しく解明しました!構造体は、プロトコルのmutatingを非突然変異として実装してもよいが、プロトコルの非突然変異機能をmutatingとして実装することはできない。一度これらのルールを言ったら、「混乱している」ことは何もありません。ルールはルールです。

クラスには突然変異関数がありませんので、あなたの調査には無関係です。プロトコルをclassプロトコルとして宣言していた場合、プロトコルのmutating注釈は不正です。

+1

私のオンラインブック(http://www.apeth.com/swiftBook/ch04.html#_declaring_a_protocol)は、同じことを言っているでしょう:「プロトコルがそれを欠いているならば、アダプターは「突然変異」を加えることができません。採用者は、プロトコルにそれがあれば、「突然変異」を省略することができる。 – matt

+0

私の質問は、funcをプロトコルの中で突然変異として宣言したときに、私たちがそれを実装するときにfuncを突然変異させてはいけないのですか?あなたの説明をありがとう。プロトコルがそれを欠くならば、アダプターは突然変異を加えることができませんが、プロトコルがそれを持っているならば、アダプターは突然変異を省略するかもしれません。私の混乱を解消した。 – iamyogish

+0

ありがとう、受け入れ/アップヴォートに感謝しますが、私を信じて、あなたはすでにこれを完全に理解していました!あなたの探偵作品は素晴らしいものでした。あなたは事実を正確に正確に表現しました。本当に知ることはもうありません。 – matt

関連する問題