Enumerations are often created to support a specific class or structure’s functionality. Similarly, it can be convenient to define utility classes and structures purely for use within the context of a more complex type. To accomplish this, Swift enables you to define nested types, whereby you nest supporting enumerations, classes, and structures within the definition of the type they support.
枚举常常被创建来支持一个特定的类或结构的功能。相似的,如果能在一个稍微复杂的类型中定义工具类和结构的话,将会非常方便。为了满足这个需要,swift可以定义嵌套类型,由此,你可以在它们支持的类型的定义中嵌套枚举,类和结构。
To nest a type within another type, write its definition within the outer braces of the type it supports. Types can be nested to as many levels as are required.
为了把一个类型嵌套到另一个类型,只需把它的定义写在他支持的类型的外层括号内。如果需要的话,可以多层嵌套。
嵌套类型实战
The example below defines a structure called BlackjackCard, which models a playing card as used in the game of Blackjack. The BlackJack structure contains two nested enumeration types called Suit and Rank.
下面的例子中定义了一个BlackjackCard结构,BlackjackCard包含两个嵌套的枚举类型Suit和Rank。
struct BlackjackCard {
// nested Suit enumeration
enum Suit: Character {
case spades = "♠", hearts = "♡", diamonds = "♢", clubs = "♣"
}
// nested Rank enumeration
enum Rank: Int {
case two = 2, three, four, five, six, seven, eight, nine, ten
case jack, queen, king, ace
struct Values {
let first: Int, second: Int?
}
var values: Values {
switch self {
case .ace:
return Values(first: 1, second: 11)
case .jack, .queen, .king:
return Values(first: 10, second: nil)
default:
return Values(first: self.rawValue, second: nil)
}
}
}
// BlackjackCard properties and methods
let rank: Rank, suit: Suit
var description: String {
var output = "suit is \(suit.rawValue),"
output += " value is \(rank.values.first)"
if let second = rank.values.second {
output += " or \(second)"
}
return output
}
}
let theAceOfSpades = BlackjackCard(rank: .ace, suit: .spades)
print("theAceOfSpades: \(theAceOfSpades.description)")
// Prints "theAceOfSpades: suit is ♠, value is 1 or 11"
The Suit enumeration describes the four common playing card suits, together with a raw Character value to represent their symbol.
suit枚举描述了四种牌的花色,并且定义了Character值。
The Rank enumeration describes the thirteen possible playing card ranks, together with a raw Int value to represent their face value. (This raw Int value is not used for the Jack, Queen, King, and Ace cards.)
rank枚举描述了十三种可能的牌的值,并定义了int值来代表他们的值(这些int值不能用于代表j q k a 这些牌)。
As mentioned above, the Rank enumeration defines a further nested structure of its own, called Values. This structure encapsulates the fact that most cards have one value, but the Ace card has two values. The Values structure defines two properties to represent this:
rank枚举还定义了一个嵌套的结构,Values。这个结构封装了一个结构:多数牌只有一个值,但是牌ace有两个值。Values结构定义了两个属性来表示此结构:
first, of type Int
second, of type Int?, or “optional Int”
first, int 类型
second,int?类型
Rank also defines a computed property, values, which returns an instance of the Values structure. This computed property considers the rank of the card and initializes a new Values instance with appropriate values based on its rank. It uses special values for jack, queen, king, and ace. For the numeric cards, it uses the rank’s raw Int value.
rank还定义了一个组合属性—values,values返回一个Values结构的实例。这个组合属性基于它自己的rank值初始化一个新的Values实例。它使用特殊值来表示jack,queen,king,和ace。对于数字牌,它使用rank的原始int值表示。
Because BlackjackCard is a structure with no custom initializers, it has an implicit memberwise initializer, as described in Memberwise Initializers for Structure Types. You can use this initializer to initialize a new constant called theAceOfSpades:
由于BlackjackCard没有自定义的初始化方法,所以它有一个隐式的逐一成员初始化方法,这在结构类型的文档中有描述。你可以使用这个初始化方法来初始化一个新的实例theAceOfSpades:
let theAceOfSpades = BlackjackCard(rank: .ace, suit: .spades)
print("theAceOfSpades: \(theAceOfSpades.description)")
// Prints "theAceOfSpades: suit is ♠, value is 1 or 11"
Even though Rank and Suit are nested within BlackjackCard, their type can be inferred from context, and so the initialization of this instance is able to refer to the enumeration cases by their case names (.ace and .spades) alone. In the example above, the description property correctly reports that the Ace of Spades has a value of 1 or 11.
即使Rank 和 Suit 嵌套在BlackjackCard中,还是可以从上下文中引用它们的类型,这个实例的初始化方法也能通过枚举的case名(.ace 和 .spades)引用枚举的case。在上面的例子中,属性描述正确地表明Ace of Spades的value为1或11;
引用嵌套类型
let heartsSymbol = BlackjackCard.Suit.hearts.rawValue
// heartsSymbol is "♡"