import Foundation
/*常量和变量***********************************************/
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0
var x = 0.0,y = 0.0,z = 0.0
//如果你的代码中有不需要改变的值,请使用 let 关键字将它声明为常量。只将需要改变的值声明为变量。
//类型标注
var welcomeMessage: String
welcomeMessage = "Hello"
var red,green,blue: Double
//你可以用任何你喜欢的字符作为常量和变量名,包括 Unicode 字符:
// 常量与变量名不能包含数学符号,箭头,保留的(或者非法的)Unicode 码位,连线与制表符。也不能以数字开 头,但是可以在常量与变量名的其他地方包含数字。
let π = 3.14159
let 你好 = "你好世界"
var friendlyWelcome = "Hello!"
friendlyWelcome = "Bonjour!"
// friendlyWelcome 现在是 "Bonjour!"
let languageName = "Swift"
//languageName = "Swift++"
// 这会报编译时错误 - languageName 不可改变
print("The current value of friendlyWelcome is \(friendlyWelcome)")
// 输出 "The current value of friendlyWelcome is Bonjour!
/*注释***********************************************/
// 这是一个注释
/* 这是一个,
多行注释 */
/* 这是第一个多行注释的开头
/* 这是第二个被嵌套的多行注释 */
这是第一个多行注释的结尾 */
/*分号***********************************************/
//与其他大部分编程语言不同,Swift 并不强制要求你在每条语句的结尾处使用分号( ; ),当然,你也可以按照你 自己的习惯添加分号。有一种情况下必须要用分号,即你打算在同一行内写多条独立的语句
let cat = "?"; print("输出:\(cat)") // 输出 "?"
/*整数***********************************************/
//Swift 提供了8,16,32和64位的有符号和无符号整数类型。这些整数类型和 C 语言的命名方式很像,比如8位 无符号整数类型是 UInt8,32位有符号整数类型是 Int32 。就像 Swift 的其他类型一样,整数类型采用大写命名 法。
//整数范围
let minValue = UInt8.min // minValue 为 0,是 UInt8 类型
let maxValue = UInt8.max // maxValue 为 255,是 UInt8 类型
print("UInt8 类型的min:\(minValue)")
print("UInt8 类型的max:\(maxValue)")
//Int类型
//在32位平台上,Int和Int32长度相同。
//在64位平台上,Int和Int64长度相同。
//UInt类型
//在32位平台上,UInt和UInt32长度相同。
//在64位平台上,UInt和UInt64长度相同。
//注意:
//尽量不要使用UInt,除非你真的需要存储一个和当前平台原生字长相同的无符号整数。除了这种情况,最好使用Int,即使你要存储的值已知是非负的。统一使用Int可以提高代码的可复用性,避免不同类型数字之间的转 换,并且匹配数字的类型推断
/*浮点数***********************************************/
//Double表示64位浮点数。当你需要存储很大或者很高精度的浮点数时请使用此类型。
//Float表示32位浮点数。精度要求不高的话可以使用此类型。
//注意:
//Double精确度很高,至少有15位数字,而Float最少只有6位数字。选择哪个类型取决于你的代码需要处理的值的范围。
/*类型安全和类型推断***********************************************/
//因为有类型推断,和 C 或者 Objective-C 比起来 Swift 很少需要声明类型。常量和变量虽然需要明确类型,但 是大部分工作并不需要你自己来完成。
//当推断浮点数的类型时,Swift 总是会选择 Double 而不是 Float
/*数值型字面量***********************************************/
//一个十进制数,没有前缀
//一个二进制数,前缀是 0b
//一个八进制数,前缀是 0o
//一个十六进制数,前缀是 0x
//下面的所有整数字面量的十进制值都是 17 :
let decimalInteger = 17
let binaryInteger = 0b10001 // 二进制的17
let octalInteger = 0o21 // 八进制的17
let hexadecimalInteger = 0x11 // 十六进制的17
// 如果一个十进制数的指数为exp,那这个数相当于基数和10^exp的乘积:1.25e2表示 1.25 × 10^2,等于125.0。1.25e-2表示 1.25 × 10^-2,等于0.0125
// 如果一个十六进制数的指数为exp,那这个数相当于基数和2^exp的乘积:0xFp2表示 15 × 2^2,等于60.0。0xFp-2表示 15 × 2^-2,等于3.75
let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0
//数值类字面量可以包括额外的格式来增强可读性。整数和浮点数都可以添加额外的零并且包含下划线,并不会影响字面量:
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
print(oneMillion)
print(justOverOneMillion)
/*数值型类型转换***********************************************/
//let cannotBeNegative: UInt8 = -1
// UInt8 类型不能存储负数,所以会报错
//let tooBig: Int8 = Int8.max + 1
// Int8 类型不能存储超过最大值的数,所以会报错
//整数和浮点数的转换必须显式指定类型:
let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// pi 等于 3.14159,所以被推测为 Double 类型
/*类型别名***********************************************/
//类型别名(type aliases)就是给现有类型定义另一个名字。你可以使用 typealias 关键字来定义类型别名。
typealias AudioSample = UInt16
var maxAmplitudeFound = AudioSample.max
print("maxAmplitudeFound is \(maxAmplitudeFound)")
/*布尔值***********************************************/
let orangesAreOrange = true
let turnipsAreDelicIoUs = false
if turnipsAreDelicIoUs {
print("Mmm,tasty turnips!")
} else {
print("Eww,turnips are horrible.")
}
// 输出 "Eww,turnips are horrible."
//let i = 1
//if i {
// 这个例子不会通过编译,会报错
//}
let i = 1
if i == 1 {
// 这个例子会编译成功
}
/*元祖***********************************************/
//元组(tuples)把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。
let http404Error = (404,"Not Found")
// http404Error 的类型是 (Int,String),值是 (404,"Not Found")
//你可以将一个元组的内容分解(decompose)成单独的常量和变量,然后你就可以正常使用它们了:
let (statusCode,statusMessage) = http404Error
print("The status code is \(statusCode)")
// 输出 "The status code is 404"
print("The status message is \(statusMessage)")
// 输出 "The status message is Not Found"
//如果你只需要一部分元组值,分解的时候可以把要忽略的部分用下划线( _ )标记:
let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)") // 输出 "The status code is 404"
//此外,你还可以通过下标来访问元组中的单个元素,下标从零开始:
print("The status code is \(http404Error.0)")
// 输出 "The status code is 404"
print("The status message is \(http404Error.1)")
// 输出 "The status message is Not Found"
//你可以在定义元组的时候给单个元素命名:
let http200Status = (statusCode: 200,description: "OK")
//给元组中的元素命名后,你可以通过名字来获取这些元素的值:
print("The status code is \(http200Status.statusCode)")
// 输出 "The status code is 200"
print("The status message is \(http200Status.description)")
// 输出 "The status message is OK"
//作为函数返回值时,元组非常有用。一个用来获取网页的函数可能会返回一个 (Int,String) 元组来描述是否获取 成功。和只能返回一个类型的值比较起来,一个包含两个不同类型值的元组可以让函数的返回信息更有用
//注意:元组在临时组织值的时候很有用,但是并不适合创建复杂的数据结构。如果你的数据结构并不是临时使用,请使用类或者结构体而不是元组。
/*可选类型***********************************************/
//使用可选类型(optionals)来处理值可能缺失的情况。可选类型表示:
//? 有值,等于 x
//或者
//? 没有值
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber 被推测为类型 "Int?",或者类型 "optional Int"
let possibleNumber2 = "abc"
let convertedNumber2 = Int(possibleNumber2)
print("convertedNumber is \(convertedNumber),convertedNumber2 is \(convertedNumber2)")
//你可以给可选变量赋值为 nil 来表示它没有值:
var serverResponseCode: Int? = 404
// serverResponseCode 包含一个可选的 Int 值 404
serverResponseCode = nil
// serverResponseCode 现在不包含值
//注意:nil 不能用于非可选的常量和变量。如果你的代码中有常量或者变量需要处理值缺失的情况,请把它们声明成对应的可选类型
//如果你声明一个可选常量或者变量但是没有赋值,它们会自动被设置为 nil :
var surveyAnswer: String?
// surveyAnswer 被自动设置为 nil
//注意:Swift 的 nil 和 Objective-C 中的 nil 并不一样。在 Objective-C 中,nil 是一个指向不存在对象的指针。在 Swift 中,nil 不是指针——它是一个确定的值,用来表示值缺失。任何类型的可选状态都可以被设置为 nil,不只是对象类型。
if convertedNumber != nil {
print("convertedNumber contains some integer value.")
}
// 输出 "convertedNumber contains some integer value."
if convertedNumber != nil {
print("convertedNumber has an integer value of \(convertedNumber!).")
}
// 输出 "convertedNumber has an integer value of 123."
//注意:使用 ! 来获取一个不存在的可选值会导致运行时错误。使用 ! 来强制解析值之前,一定要确定可选包含一个非nil 的值。
if let actualNumber = Int(possibleNumber) {
print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
} else {
print("\'\(possibleNumber)\' could not be converted to an integer")
}
// 输出 "'123' has an integer value of 123"
//隐式解析可选类型
//下面的例子展示了可选类型 String 和隐式解析可选类型 String 之间的区别:
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // 需要惊叹号来获取值
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // 不需要感叹号
//你可以把隐式解析可选类型当做一个可以自动解析的可选类型。你要做的只是声明的时候把感叹号放到类型的结尾,而不是每次取值的可选名字的结尾。
//注意:如果你在隐式解析可选类型没有值的时候尝试取值,会触发运行时错误。和你在没有值的普通可选类型后面加一个惊叹号一样。
//你仍然可以把隐式解析可选类型当做普通可选类型来判断它是否包含值:
if assumedString != nil {
print(assumedString)
}
// 输出 "An implicitly unwrapped optional string."
//你也可以在可选绑定中使用隐式解析可选类型来检查并解析它的值:
if let definiteString = assumedString {
print(definiteString)
}
// 输出 "An implicitly unwrapped optional string."
/*错误处理***********************************************/
//当一个函数遇到错误条件,它能报错。调用函数的地方能抛出错误消息并合理处理。
func canThrowAnErrow() throws {
}
//一个函数可以通过在声明中添加 throws 关键词来抛出错误消息。当你的函数能抛出错误消息时, 你应该在表达式 中前置 try 关键词。
do {
try canThrowAnErrow() // 没有错误消息抛出
} catch {
// 有一个错误消息抛出
}
func makeASandwich() throws {
// ...
}
//do {
// try makeASandwich()
// eatASandwich()
//} catch Error.OutOfCleanDishes {
// washDishes()
//} catch Error.MissingIngredients(let ingredients) {
// buyGroceries(ingredients)
//}
/*断言***********************************************/