[英]Swift: Undeclared Variable with Multiple Type Options
I'm learning swift through Apple's App Development book. 我正在学习Apple的App Development书。 There is a project for designing a Favorite Athlete App to view, add and edit athletes. 有一个项目旨在设计一个最喜欢的运动员应用程序,以查看,添加和编辑运动员。
I'm wondering if there is a way to have a variable in a struct/class that is of a type that is dependent on the literal of another variable.... 我想知道是否有一种方法可以在结构/类中具有依赖于另一个变量的文字类型的类型。
Ok, so this is what I'm thinking. 好的,这就是我的想法。
enum League {
case MLB, NFL, NBA
}
enum MLB {
case Braves, Yankees, Red Sox
}
enum NFL {
case Falcons, Giants, Patriots
}
enum NBA {
case Hawks, Knicks, Celtics
}
struct Athlete {
var name: String
var age: Int
var league: League
var Team: switch league{
case .MLB:
return MLB enum
case .NFL:
return NFL enum
case .NBA:
return NBA enum
}
}
You can't have spaces in enum cases. 枚举情况下不能有空格。 Per convention, you should use lowerCamelCase. 按照约定,您应该使用lowerCamelCase。 Just from looking at your code, it looks like you're looking for something like this: 仅仅通过查看您的代码,就好像您在寻找这样的东西:
enum League {
case mlb, nfl, nba
}
protocol LeagueTeam {
static var league: League { get }
}
enum MLBTeams: LeagueTeam {
case braves, yankees, redSox
static let league = League.mlb
}
enum NFLTeams: LeagueTeam {
case falcons, giants, patriots
static let league = League.nfl
}
enum NBATeams: LeagueTeam {
case hawks, knicks, celtics
static let league = League.nba
}
struct Athlete {
var name: String
var age: Int
var team: LeagueTeam
var league: League { return type(of: team).league }
}
I like Alexander's solution, but this also lends itself nicely to enums with associated data: 我喜欢Alexander的解决方案,但这也很适合与关联数据进行枚举:
enum MLBTeam {
case braves, yankees, redSox
}
enum NFLTeam {
case falcons, giants, patriots
}
enum NBATeam {
case hawks, knicks, celtics
}
enum Team {
case mlb(MLBTeam)
case nfl(NFLTeam)
case nba(NBATeam)
}
struct Athlete {
var name: String
var age: Int
var team: Team
}
let athlete = Athlete(name: "Julio Teherán", age: 26, team: .mlb(.braves))
With this, you can use the team
property to switch both on specific teams and on leagues. 这样,您可以使用team
属性来同时打开特定的团队和联赛。
switch athlete.team {
case .mlb: print("Baseball")
case .nfl: print("Football")
case .nba: print("Basketball")
}
switch athlete.team {
case .mlb(.braves): print("Braves")
default: print("Not Braves")
}
The one sad thing in Swift 4 is that it still can't auto-generate Equatable
for enums with associated values, so you have to do that by hand if you want it. Swift 4中令人难过的一件事是,它仍然无法为带有关联值的枚举自动生成Equatable
,因此,如果需要,您必须手动执行。
extension Team: Equatable {
static func ==(lhs: Team, rhs: Team) -> Bool {
switch (lhs, rhs) {
case let (.mlb(lhsTeam), .mlb(rhsTeam)): return lhsTeam == rhsTeam
case let (.nfl(lhsTeam), .nfl(rhsTeam)): return lhsTeam == rhsTeam
case let (.nba(lhsTeam), .nba(rhsTeam)): return lhsTeam == rhsTeam
default: return false
}
}
}
It's difficult to get Alexander's solution to allow ==
on LeagueTeam
. 要获得Alexander的解决方案在LeagueTeam
上允许==
LeagueTeam
。 Making LeagueTeam
conform to Equatable
creates all kinds of problems, and you can't create an exhaustive switch
over LeagueTeam
because it can have arbitrary implementations. 使LeagueTeam
符合Equatable
会产生各种问题,并且您不能对LeagueTeam
进行详尽的switch
,因为它可以具有任意实现。 So that's one nice thing about using an enum here. 因此,在此处使用枚举是一件好事。
On the other hand, using an enum pushes you into exhaustive switch statements, which may be a problem if the leagues or team list may change. 另一方面,使用枚举会使您进入详尽的切换语句,如果联盟或球队名单可能更改,则可能会出现问题。 (On the other hand, it may be a benefit…) (另一方面,这可能是一个好处……)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.