import UIKit
//結構體和枚舉是值類型
//值類型被賦予給一個變量、常量或者被傳遞給一個函數的時候,其值會被拷貝。
struct BlackjackCard {
//嵌套定義枚舉型suit
enum Suit: String {//定義了原始值
case Spades = "紅桃", Hearts = "黑桃", Diamonds = "方片" ,Clubs = "梅花"
}
//嵌套定義枚舉Rank
enum Rank: Int{
case Two = 2,Three,Four,Five,Six,Seven,Eight,Nine,Ten
case J,Q,K,A
struct Values {
let first : Int,second :Int?
}
var values:Values{
switch self{
case .A:
return Values(first: 1, second: 11)
case .J, .Q, .K:
return Values(first: 10, second: nil)
default:
return Values(first: self.rawValue, second: nil)
}
}
}
//BlackjackCard 的屬性和方法
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
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//嵌套類型
//枚舉類型常被用於實現特定類或結構體的功能。也能購在有多種變量類型的環境中,方便地定義通用類或結構體來使用。爲了實現這種功能,swift允許你定義嵌套類型,可以在枚舉類型、類、和結構體中定義支持嵌套的類型
let theAceOfSpades = BlackjackCard(rank: .A, suit: .Hearts)
print("theAofHearts:\(theAceOfSpades.description)")
//theAofHearts:suit is 黑桃value is 1or 11
let theAceOfSpades2 = BlackjackCard(rank: .Four, suit: .Hearts)
print("theAofHearts:\(theAceOfSpades2.description)")
//theAofHearts:suit is 黑桃value is 4
//儘管Rank和Suit嵌套在BlackjackCard中,但仍可被引用,所以在初始化實例時能夠通過枚舉類型中的成員名稱單獨引用。
//在外部對嵌套類型的引用,以被嵌套類型的名字爲前綴,加上所要引用的屬性名
let heartsSymbol = BlackjackCard.Suit.Hearts.rawValue
print("\(heartsSymbol)")//黑桃
//擴展(Extensions)
//擴展就是向一個已有的類、結構體、枚舉類型或協議類型添加新功能。
//與oc不同的是,swift的擴展沒有名字
//swift中的擴展可以:添加計算型屬性和計算型靜態屬性、定義實例方法和類型方法、提供新的構造器、定義下標、定義和使用新的嵌套類型、使一個已有類型符合某個協議
//擴展可以對一個類型添加新的功能,但是不能重寫已有的功能
//擴展可以向已有類型添加計算型實例屬性和計算型屬性。
let oneInch = 25.4.mm
print("One inch is \(oneInch) meters")//One inch is 0.0254 meters
let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")//Three feet is 0.914634146341463 meters
let aMarathon = 42.km + 195.m
print("A marathon is \(aMarathon) meters long")
//A marathon is 42195.0 meters long
//擴展能向類中添加新的便利構造器,但是它們不能向類中添加新的指定構造器或析構器。指定構造器和析構器必須總是由原始的類實現來提供
//因爲結構體Rect提供了其所有屬性的默認值,所以它可以自動接受一個默認構造器和一個逐一成員構造器。
let defaultRect = Rect()
let otherRect = Rect(origin: Point(x: 2.0, y: 2.0), size: Size(width: 5.0, height: 5.0))
let centerRect = Rect(center: Point(x: 4.0, y: 4.0), size: Size(width: 3.0, height: 3.0))
//擴展可以向已有類型添加新的實例方法和類型方法。
4.repetitions { () -> () in
print("hello!")
}//尾隨閉包
// hello!
// hello!
// hello!
// hello!
//通過擴展添加的實例方法也可以修改該實例本身。結構體和枚舉類型中修改self或其屬性的方法必須將該實例方法標註爲mutaing。
var someInt = 3
someInt.square()
print("\(someInt)");//9
//擴展可以向一個已有類型添加新下標。
print(12345[0])//5
print(12345[1])//4
//擴展可以向已有的類、結構體和枚舉添加新的嵌套類型
printIntKinds([3,-4,0,5,-6])
//+ - 0 + -
}
}
func printIntKinds(numbers:[Int]){
for number in numbers{
switch number.kind{//已知number.kind是Int.Kind型,所以使用.Negative代替Int.kind.Negative
case .Negative:
print("-")
case .Zero:
print("0")
case .Positive:
print("+")
}
}
}
extension Int{
enum Kind{//添加了新的嵌套枚舉
case Negative,Zero,Positive
}
var kind:Kind{
switch self{
case 0:
return .Zero
case let x where x>0:
return .Positive
default:
return .Negative
}
}
}
extension Int{
subscript(var digitIndex:Int)->Int{
var decimalBase=1
while digitIndex > 0{
decimalBase *= 10
--digitIndex
}
return (self / decimalBase) % 10
}
}
extension Int{//結構體和枚舉類型中修改self或其屬性的方法必須將該實例方法標註爲mutaing。
mutating func square(){
self = self * self
}
}
extension Int{
func repetitions(task:()->()){//()->()表明函數沒有參數而且沒有返回值。
for i in 0..<self{
task()
}
}
}
extension Rect{
init(center:Point,size:Size){
let originX = center.x - (size.width/2)
let originY = center.y - (size.height/2)
self.init(origin:Point(x: originX, y: originY),size:size)//自帶的逐一成員構造器
}
}
struct Size {
var width = 0.0, height = 0.0
}
struct Point {
var x = 0.0, y = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
}
extension Double{
var km :Double{return self * 1_000.0}
var m :Double{return self}
var cm: Double{return self / 100.0}
var mm :Double {return self / 1_000.0}
var ft : Double{return self / 3.28}
}