2017-10-10 14 views
0

J'essaie de créer un protocole avec des méthodes par défaut qui mettent à jour une propriété nommée. Malheureusement, je reçois une erreur Left side of mutating operator isn't mutable…Puis-je mettre à jour la propriété spécifiée dans l'extension de protocole?

protocol Weapon { 
    var energy: Int { get set } 
    var fireEnergy: Int { get } 
    var rechargeRate: Int { get } 

    func fire() 
    func recharge() 
} 

extension Weapon { 
    var fireEnergy: Int { 
     return 10 
    } 

    var rechargeRate: Int { 
     return 2 
    } 

    func fire() { 
     guard energy >= fireEnergy else { return } 
     energy -= fireEnergy // <- Error Here 
    } 

    func recharge() { 
     energy += rechargeRate // <- Error Here 
    } 
} 

class PhaseCannon: Weapon { 
    var energy = 0 
} 

Si je change les méthodes pour muter comme suggéré, je reçois une erreur au point d'utilisation pour la méthode d'incendie. Cannot use mutating member on immutable value…

var weapons = [PhaseCannon()] 

for weapon in weapons { 
    weapon.fire() // <- Error here 
} 

Puis-je pas faire cela?

+0

'PhaseCannon' est une classe ou un struct? –

+0

@Aaron Bratcher pouvez-vous partager Phase Canon classe –

+0

en utilisant le mot-clé 'mutation 'à' -fire() 'et' -recharge() 'probablement nécessaire ici; D'autre part, à l'intérieur de votre itération, vous ne pouvez pas utiliser la méthode de mutation sur un type local immuable. – holex

Répondre

0

Votre deuxième erreur est parce que arme dans pour le cycle est laissez. Le plus rapide solution possible est que vous pouvez changer votre code:

var weapons = [PhaseCannon()] 
var newWeapons: [PhaseCannon] 

for weapon in weapons { 
    var updatedWeapon = weapon 
    updatedWeapon.fire() // <- Error here 
    newWeapons.append(weapon) 
} 
+0

J'ai trouvé que si je change les méthodes de mutation et que je fais la boucle for comme pour var arme dans les armes, cela fonctionne correctement. C'est juste bizarre qu'une instance de classe doive être un var. –

+0

@AaronBratcher, génial, c'est encore mieux :) –

0

Si votre permis refactorisation de code existant, je suggère tourner PhaseCannon dans une classe plutôt que d'une struct.

Sinon, vous pouvez changer votre boucle de mise à jour comme celui-ci:

for index in weapons.indices 
{ 
    weapons[index].fire() 
}