枚举中的类参数

时间:2016-06-05 11:11:49

标签: swift struct enums

我有一个关于如何一起使用枚举和类的问题。

请考虑以下事项:

enum parameter {
    case agility
    case strength
    case mind
}

struct heroParameters {
    let maxInitialParam: UInt32! = 10

    var agility: UInt32!
    var strength: UInt32!
    var mind: UInt32!

    init() {
        self.agility = arc4random_uniform(self.maxInitialParam)
        self.strength = arc4random_uniform(self.maxInitialParam)
        self.mind = arc4random_uniform(self.maxInitialParam)
    }
}

class Hero {
    var parameters: heroParameters!

    required init() {
         self.parameters = heroParameters()
    }

    func setParameter(parameterName: parameter, _ value: UInt32) {
         // ?
    }
}

我的问题是:有没有办法从枚举中正确设置结构变量列表,以防需要修改参数列表?

一般来说,有没有办法初始化一个由未知数量的变量组成的结构,这些变量都列在单独的枚举中?

无论哪种方式,我可能会以完全错误的方式思考,我需要了解如何正确使用这些方法。

2 个答案:

答案 0 :(得分:5)

您可以使用字典在HeroParameters中存储参数。如果您使枚举Parameter的rawValue类型为Int,则HeroParameters将能够为所有这些创建默认值,而无需提前知道有多少。

这是有效的,因为Parameter(rawValue:)会在nil达到最大枚举数后返回rawValuewhile循环将结束。

enum Parameter: Int {
    case agility
    case strength
    case mind
}

struct HeroParameters {
    let maxInitialParam: UInt32 = 10

    var parameters = [Parameter: UInt32]()

    init() {
        var rawValue = 0
        while let parameter = Parameter(rawValue: rawValue) {
             parameters[parameter] = arc4random_uniform(maxInitialParam)
             rawValue += 1
        }
    }
}

class Hero {
    var parameters = HeroParameters()

    func setParameter(parameterName: Parameter, _ value: UInt32) {
        parameters.parameters[parameterName] = value
    }
}

根据@ vadian在评论中提出的出色建议,您可以定义Hero类,并能够使用下标设置/获取参数:

class Hero {
    var parameters = HeroParameters()

    subscript(key: Parameter) -> UInt32 {
        get { return parameters.parameters[key]! }
        set { parameters.parameters[key] = newValue}
    }
}

然后,你有一个很好的清洁解决方案:

let hero = Hero()

hero[.agility] = 3
hero[.strength] = 7

print(hero[.strength])  // "7"

答案 1 :(得分:1)

简短回答:你不能直接这样做。

解决方法是在HeroParameters中声明字典并使用枚举订阅。

enum Parameter : String {
  case Agility = "agility"
  case Strength = "strength"
  case Mind = "mind"

  static let allValues = [Agility, Strength, Mind]
}

struct HeroParameters {
  let maxInitialParam: UInt32 = 10

  var parameters = [String:UInt32]()

  subscript(key: Parameter) -> UInt32 {
    get { return parameters[key.rawValue]! }
    set { parameters[key.rawValue] = newValue }
  }

  init() {
    for aValue in Parameter.allValues {
      self[aValue] = arc4random_uniform(maxInitialParam)
    }
  }
}

class Hero {
  var parameters: HeroParameters

  required init() {
    self.parameters = HeroParameters()
  }

  func setParameter(parameterName: Parameter, _ value: UInt32) {
    parameters[parameterName] = value
  }

  func parameterForKey(key: Parameter) -> UInt32 {
     return parameters[key]
  }
}


let hero = Hero()
let strength = hero.parameterForKey(.Strength)
hero.setParameter(.Strength, 8)

let agility = hero.parameterForKey(.Agility)
let newStrength = hero.parameterForKey(.Strength)

所有变量都被声明为非选项,并且由于枚举案例的数量和值在设计时是众所周知的,因此所有强制解包的值都绝对安全。

编辑:

根据vacawama的回答和Sulthan的建议,这是一个基于阵列的版本

enum Parameter: Int {
  case Agility, Strength, Mind
}

struct HeroParameters {
  let maxInitialParam: UInt32 = 10

  var parameters = [UInt32]()

  init() {
    var rawValue = 0
    while Parameter(rawValue: rawValue) != nil {
      parameters.append(arc4random_uniform(maxInitialParam))
      rawValue += 1
    }
  }
}

class Hero {
  var parameters = HeroParameters()

  subscript(key: Parameter) -> UInt32 {
    get { return parameters.parameters[key.rawValue] }
    set { parameters.parameters[key.rawValue] = newValue }
  }
}


let hero = Hero()
hero[.Strength] = 8

let agility = hero[.Agility]
let newStrength = hero[.Strength]