I’m trying to learn how to use protocols and extensions to factor out redundant function bodies.
Supposedly in a protocol, “Self” is the class implementing the protocol. So it seems to me that extension methods should be able to have a return type of Self so they can return self, and thus have the extension method behave the same as it would as if it were defined in the class adopting the protocol. But it seems as if that’s not the case, because in the code below, when I return “self” from the extension’s function bodies in order to enable method chaining, I get a compiler error. I’m told the class is immutable. If I move those bodies into the separate classes adopting the protocol and change Self to the name of the class, then everything works as expected. Is it possible to get the code working, or am I tilting at a windmill? I can imagine there’s just some minor syntax gotcha of which I’m unaware; but then again maybe there’s just no way to return a mutable self from a protocol-extension function body. BTW, I wondered if it was a reference type vs value type thing, so I tested: it doesn’t matter whether I define these classes as classes or structs; the error message is the same. import SpriteKit // Create a protocol specifying the items an action collection // must have in order for us to do fluent configuration using // chained method calls protocol SKActionCollection { var list: [SKAction] { get set } // Should be mutable! var action: SKAction { get } } // Use an extension to define methods common to both types // of action collection extension SKActionCollection { mutating func withAction( target: SKAction ) -> Self { list.append( target ) return self } mutating func withBlock( block: ()->() ) -> Self { return withAction( SKAction.runBlock( block )) } mutating func withDelay( duration: NSTimeInterval ) -> Self { return withAction( SKAction.waitForDuration( duration )) } // ... Many other useful mutating functions omitted func performOnceOn( node: SKNode ) { node.runAction( action ) } } extension SKAction { struct Fluent { // Fluent configuration for an action collection which // runs the actions sequentially class Sequence : SKActionCollection { var list = [SKAction]() var action: SKAction { return SKAction.sequence( list ) } } // Fluent configuration for an action collection which // runs the actions concurrently class Group : SKActionCollection { var list = [SKAction]() var action: SKAction { return SKAction.group( list ) } } } } // Try to use fluent configuration to define action collections // I get the same error, saying my function call (to the constructor?) // returns an immutable value, regardless of whether I use var or let var sequence = SKAction.Fluent.Sequence() .withDelay( 0.5 ) .withBlock( { print( "I did something in sequence!" ) } ) .action let group = SKAction.Fluent.Group() .withBlock( { print( "A group of one action is really pitiful" ) } ) .action -- Charles _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com