我有一个关于如何一起使用枚举和类的问题。
请考虑以下事项:
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) {
// ?
}
}
我的问题是:有没有办法从枚举中正确设置结构变量列表,以防需要修改参数列表?
一般来说,有没有办法初始化一个由未知数量的变量组成的结构,这些变量都列在单独的枚举中?
无论哪种方式,我可能会以完全错误的方式思考,我需要了解如何正确使用这些方法。
答案 0 :(得分:5)
您可以使用字典在HeroParameters
中存储参数。如果您使枚举Parameter
的rawValue类型为Int
,则HeroParameters
将能够为所有这些创建默认值,而无需提前知道有多少。
这是有效的,因为Parameter(rawValue:)
会在nil
达到最大枚举数后返回rawValue
,while
循环将结束。
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]