let age = -3 assert(age >= 0, "A person's age cannot be less than zero") // 因为 age < 0,所以断言会触发
基本运算符
赋值运算符,算术运算符,组合赋值运算符,比较运算符,三元运算符,空合运算符,区间运算符,逻辑运算符 运算符分为一元、二元和三元运算符。 闭区间运算符(a…b)定义一个包含从 a 到 b(包括 a 和 b)的所有值的区间。 半开区间运算符(a..<b)定义一个从 a 到 b 但不包括 b 的区间。 闭区间操作符有另一个表达形式,可以表达往一侧无限延伸的区间,(a…,…b)。
1 2 3 4 5
let names = ["Anna", "Alex", "Brian", "Jack"] letcount = names.count for i in 0..<count { print("第 \(i + 1) 个人叫 \(names[i])") }
字符串和字符
字符串字面量,字符串插值,计算字符数量,访问和修改字符串,子字符串,比较字符串 初始化空字符串,字符串可变性,字符串是值类型,连接字符串和字符(+,+=)。 使用字符,可通过 for-in 循环来遍历字符串,获取字符串中每一个字符的值。 字符串插值是一种构建新字符串的方式,可以在其中包含常量、变量、字面量和表达式。可以在已有字符串中插入常量、变量、字面量和表达式从而形成更长的字符串。 Swift 提供了三种方式来比较文本值:字符串字符相等、前缀相等和后缀相等。
// 函数 funcgreet(person: String) -> String { let greeting ="Hello, "+ person +"!" return greeting }
funcgreet(person: String, fromhometown: String) -> String { return"Hello \(person)! Glad you could visit from \(hometown)." } print(greet(person: "Bill", from: "Cupertino")) // 打印“Hello Bill! Glad you could visit from Cupertino.”
// 可选元组返回类型 funcminMax(array: [Int]) -> (min: Int, max: Int)? { if array.isEmpty { returnnil } var currentMin = array[0] var currentMax = array[0] for value in array[1..<array.count] { if value < currentMin { currentMin = value } elseif value > currentMax { currentMax = value } } return (currentMin, currentMax) }
let somePlanet =Planet.earth switch somePlanet { case .earth: print("Mostly harmless") default: print("Not a safe place for humans") } // 打印“Mostly harmless”
// 关联值 enumBarcode { case upc(Int, Int, Int, Int) case qrCode(String) } var productBarcode =Barcode.upc(8, 85909, 51226, 3) productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
// 递归枚举 indirectenumArithmeticExpression { case number(Int) case addition(ArithmeticExpression, ArithmeticExpression) case multiplication(ArithmeticExpression, ArithmeticExpression) } let five =ArithmeticExpression.number(5) let four =ArithmeticExpression.number(4) let sum =ArithmeticExpression.addition(five, four) let product =ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2)) // (5 + 4) * 2
// 属性 struct Point { var x = 0.0, y = 0.0 } struct Size { varwidth = 0.0, height = 0.0 } struct Rect { var origin = Point() var size = Size() //存储属性 var center: Point { //计算型属性 get { let centerX = origin.x + (size.width / 2) let centerY = origin.y + (size.height / 2) return Point(x: centerX, y: centerY) } set(newCenter) { origin.x = newCenter.x - (size.width / 2) origin.y = newCenter.y - (size.height / 2) } } } var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0)) let initialSquareCenter = square.center square.center = Point(x: 15.0, y: 15.0) print("square.origin is now at (\(square.origin.x), \(square.origin.y))") // 打印“square.origin is now at (10.0, 10.0)”
// 属性包装器 @propertyWrapper struct TwelveOrLess { private var number = 0 var wrappedValue: Int { get { return number } set { number = min(newValue, 12) } } }
subscript(index: Int) -> Int { get { // 返回一个适当的 Int 类型的值 } set(newValue) { // 执行适当的赋值操作 } }
// 示例 structTimesTable { let multiplier: Int subscript(index: Int) -> Int { return multiplier * index } } let threeTimesTable =TimesTable(multiplier: 3) print("six times three is \(threeTimesTable[6])") // 打印“six times three is 18”
classVehicle { var currentSpeed = 0.0 var description: String { return"traveling at \(currentSpeed) miles per hour" } func makeNoise() { // 什么也不做——因为车辆不一定会有噪音 } }
classCar: Vehicle { var gear = 1 overridevar description: String { returnsuper.description + " in gear \(gear)" } }
structFahrenheit { var temperature: Double init() { temperature =32.0 } } var f =Fahrenheit() print("The default temperature is \(f.temperature)° Fahrenheit") // 打印“The default temperature is 32.0° Fahrenheit”
structColor { let red, green, blue: Double init(red: Double, green: Double, blue: Double) { self.red = red self.green = green self.blue = blue } init(white: Double) { red = white green = white blue = white } }
析构过程
析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用。析构器用关键字 deinit 来标示,类似于构造器要用 init 来标示。 Swift 会自动释放不再需要的实例以释放资源。
classResidence { var numberOfRooms =1 } let john =Person() let roomCount = john.residence!.numberOfRooms // 这会引发运行时错误
iflet roomCount = john.residence?.numberOfRooms { print("John's residence has \(roomCount) room(s).") } else { print("Unable to retrieve the number of rooms.") } // 打印“Unable to retrieve the number of rooms.”
john.residence =Residence()
iflet roomCount = john.residence?.numberOfRooms { print("John's residence has \(roomCount) room(s).") } else { print("Unable to retrieve the number of rooms.") } // 打印“John's residence has 1 room(s).”
// 类型转换 // 一个基类 MediaItem classMediaItem { var name: String init(name: String) { self.name = name } }
classMovie: MediaItem { var director: String init(name: String, director: String) { self.director = director super.init(name: name) } }
classSong: MediaItem { var artist: String init(name: String, artist: String) { self.srtist = artist super.init(name: name) } }
let library = [ Movie(name: "Casablanca", director: "Micheal Curtiz"), Song(name: "Blue Suede Shose", artist: "Elvis Presley"), Movie(name: "Citizen Kane", director: "Orson Wells"), Song(name: "The One And Only", artist: "Chesney Hawkes"), Song(name: "Never Gonna Give You Up", artist: "Rick Astley") ] var movieCount =0 var songCount =0
for item in library { if item isMovie { movieCount +=1 } elseif item isSong { songCount +=1 } }
print("Media library contains \(movieCount) movies and \(songCount)") // 打印“Media library contains 2 movies and 3 songs”
for item in library { iflet movie = item as?Movie { print("Movie: \(movie.name), dir. \(movie.director)") } elseiflet song = item as?Song { print("Song: \(song.name), by \(song.artist)") } } // Movie: Casablanca, dir. Michael Curtiz // Song: Blue Suede Shoes, by Elvis Presley // Movie: Citizen Kane, dir. Orson Welles // Song: The One And Only, by Chesney Hawkes // Song: Never Gonna Give You Up, by Rick Astley
// 嵌套的 Rank 枚举 enumRank: Int { case two =2, three, four, five, six, seven, eight, nine, ten case jack, queen, king, ace structValues { let first: Int, second: Int? } var values: Values { switchself { case .ace: returnValues(first: 1, second: 11) case .jack, .queen, .king: returnValues(first: 10, second: nil) default: returnValues(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)" iflet second = rank.values.second { output +=" or \(second)" } return output } }
let theAceOfSpades =BlackjackCard(rank: .ace, suit: .spades) print("theAceOfSpades: \(theAceOfSpades.description)") // 打印“theAceOfSpades: suit is 1, value is 1 or 11”
let heartsSymbol =BlackjackCard.Suit.hearts.rawValue // 2
// 自动引用计数实践 classPerson { let name: String init(name: String) { self.name = name print("\(name) is being initialized") } deinit { print("\(name) is being deinitialized") } }
var reference1: Person? var reference2: Person? var reference3: Person? reference1 =Person(name: "John Appleseed") // 打印“John Appleseed is being initialized” reference2 = reference1 reference3 = reference1 reference1 =nil reference2 =nil reference3 =nil // 打印“John Appleseed is being deinitialized”
// 循环强引用 classPerson { let name: String init(name: String) { self.name = name } var apartment: Apartment? deinit { print("\(name) is being deinitialized") } }
classApartment { let unit: String init(unit: String) { self.unit = unit } var tenant: Person? deinit { print("Apartment \(unit) is being deinitialized") } } var john: Person? var unit4A: Apartment? john =Person(name: "John Appleseed") unit4A =Apartment(unit: "4A")
john =nil unit4A =nil
// 弱引用 classPerson { let name: String init(name: String) { self.name = name } var apartment: Apartment? deinit { print("\(name) is being deinitialized") } }
classApartment { let unit: String init(unit: String) { self.unit = unit } weakvar tenant: Person? deinit { print("Apartment \(unit) is being deinitialized") } }
var john: Person? var unit4A: Apartment?
john =Person(name: "John Appleseed") unit4A =Apartment(unit: "4A")
john!.apartment = unit4A unit4A!.tenant = john
john =nil // 打印“John Appleseed is being deinitialized”