Swift:具有多种类型选项的未声明变量

时间:2018-01-13 15:00:09

标签: swift struct enums

我正在通过Apple的App Development书快速学习。有一个设计喜爱的运动员应用程序的项目,以查看,添加和编辑运动员。

我想知道是否有一种方法可以在一个结构/类中拥有一个变量,该类型依赖于另一个变量的文字......

好的,这就是我的想法。

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
    } 
}

2 个答案:

答案 0 :(得分:0)

在枚举案件中你不能有空格。按照惯例,您应该使用lowerCamelCase。只是看看你的代码,看起来你正在寻找这样的东西:

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 }
}

答案 1 :(得分:0)

我喜欢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))

有了这个,你可以使用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")
}

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
        }
    }
}

很难让Alexander的解决方案在==上允许LeagueTeam。使LeagueTeam符合Equatable会产生各种问题,而且您无法创建详尽switch而不是LeagueTeam因为它可以有任意实现。所以在这里使用枚举是一件好事。

另一方面,使用枚举会将您推送到详尽的切换语句中,如果联赛或球队列表可能发生变化,这可能会出现问题。 (另一方面,这可能是一个好处......)