Swift基础知识

Swift基础知识

最近闲来无事,准备花一周时间来整理一下Swift中的相关知识,这里整理的主要是Swift官方文档的内容及自己的一些认识,有什么不准确的地方,欢迎大家指正。

这一章主要讲Swift的基础知识,旨在让大家对Swift有一个整体的了解,之后后详细的介绍各个部分的详细内容。

定义常量和变量

Swift中,只用let关键字来定义一个常量,使用var关键字来定义一个变量。

let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0

你也可以在一行中定义多个常量或多个变量,使用逗号分隔。

var x = 0.0, y = 0.0, z = 0.0

总结:

  • 一条Swift语句,不必以分号作为结尾。
  • Swift是类型安全的语言。
  • 如果存储的值不需要改变,使用let关键字将其定义为常量。如果存储的值需要改变,使用var关键字将其定义为变量。

类型注释

可以通过类型注释的方式,来清晰的指定你定义的常量或变量所能存储的值的类型。

var welcomeMessage: String
welcomeMessage = "Hello"

上面这段代码可以读为:定义一个String类型的变量。
你可以在一行定义多个常量或变量,通过逗号分隔,然后使用一个类型注释来标注它们。

var red, green, blue: Double

总结:

  • 在使用类型注释时,注意冒号后要有一个空格。
  • 在实际开发中。类型注释用的很少。如果在定义时指定初始值,Swift可以根据初始值来推断出变量/常量的类型。如果不指定初始值,则需要类型注释来指定变量/常量所能存储的值的类型。
  • 一旦常量/变量的类型确定了,它所存储的值的类型也就确定了。

变量和常量的命名

几乎可以使用任意字符来命名变量和常量,包括Unicode字符:

let π = 3.14159
let 你好 = "你好世界"

常量和变量的名称不能包括:空白字符,数学符号,箭头,私有的(或无用的)码点,或-。

总结:

  • 如果需要使用Swift预留的关键字来命名常量/变量,在变量前后加`来解决。除非没有选择,否则不要使用预留关键字来命名。

    var `var` = 123

注释

  • 单行注释:
// This is a comment.
  • 多行注释:
/* This is also a comment
but is written over multiple lines. */
  • 嵌套的多行注释:(Swift中新增的)
/* This is the start of the first multiline comment.
/* This is the second, nested multiline comment. */
This is the end of the first multiline comment. */

分号

不像其它语言,Swift中每条语句的末尾分号不是必须的。如果在一行中写多条语句,则分号是必须的。

let cat = "cat"; print(cat)
// Prints "cat"

整型

Swift提供了8,16,32和64位的有符号和无符号整型。分别为Int8/UInt8,Int16/UInt16,Int32/UInt32,Int64/UInt64。

整数范围

可以使用每个整数类型的min和max来访问最大和最小值。

let minValue = UInt8.min  // minValue is equal to 0, and is of type UInt8
let maxValue = UInt8.max  // maxValue is equal to 255, and is of type UInt8
Int

大多数情况下,你不需要在代码中选择特定大小的整数类型,这时候可以使用Int类型,Int类型的大小和当前平台的位数保持一致。

  • 在32位的平台上,Int同Int32。
  • 在64位的平台上,Int同Int64。
UInt

无符号整型。和当前平台的位数保持一致。

  • 在32位的平台上,UInt同UInt32。
  • 在64位的平台上,UInt同UInt64。

浮点数

Double代表64位浮点数。
Float代表32位浮点数。

总结:

  • Double至少要有15位的精度,而FLoat至少6位的精度。

类型安全和类型推断

Swift是一门类型安全的语言。所谓类型安全的语言,就是你要清楚你所使用的值类型。如果需要一个String类型的值,如果传递Int类型,就会产生错误。

因为Swift是类型安全的,会在编译的时候进行类型检查,并且将不匹配的类型标记为错误。可以使你尽早的在开发过程中发现错误。

在定义常量/变量时,并不需要必须指明其类型。如果在定义时没有指明类型,Swift会使用类型推断来帮助你确定合适的类型。类型推断使编译器只需检查所提供的值,就可以自动推断指定表达式的类型。

在定义一个带有初始值的常量/变量时,类型推断是非常有用的。

let meaningOfLife = 42 //meaningOfLife被推断为是Int型
let pi = 3.14159  //pi被推断为是Double类型
let anotherPi = 3 + 0.14159 //anotherPi被推断为Double类型

数值型的字面值

数值型的字面值包括:

  • 无前缀的十进制。
  • 以0b开头的二进制。
  • 以0o开头的八进制。
  • 以0x开头的十六进制。
let decimalInteger = 17           // 17的十进制表示
let binaryInteger = 0b10001       // 17的二进制表示
let octalInteger = 0o21           // 17的八进制表示
let hexadecimalInteger = 0x11     // 17的十六进制表示

所有这些字面值,都对应十进制中的17。

浮点型的字面值包括:无前缀的十进制和带有0x前缀的十六进制。十进制通过e/E指定指数,以10为底,十六进制通过p/P指定指数,以2为底。

  • 1.25e2相当于1.25 * 10²,或125.0。
  • 1.25e﹣²相当于1.25 * 10﹣², 或0.0125。
  • 0xFp2相当于15 * 2²,或60。
  • 0xFp﹣²相当于14 * 2﹣²,或3.75.

数值型字面值可以包含额外的格式,使它们更容易阅读。

let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1

数值类型转换

数值型类型转换的格式是:SomeType(ofInitialValue),这种方式相当于调用SomeType的初始化方法,新创建一个SomeType类型的实例。

整数类型间转换

直接看例子:

let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
整数和浮点数间转换

直接看例子:

let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
let integerPi = Int(pi) //integerPi的值为3
总结:
  • Swift中的类型转换同Objective-C不同,类型兼容的类型间转换也要显示使用SomeType(ofInitialValue)这种形式进行转换。

类型别名

类型别名是为已存在的类型定义一个可选的名字。使用typealias关键字来为类型定义别名。

typealias AudioSample = UInt16
var maxAmplitudeFound = AudioSample.min

布尔值

Swift中使用Bool来指定布尔值。Swift只存在两个布尔类型的常量。true和false。

let orangesAreOrange = true
let turnipsAreDelicious = false

Swift是类型安全的语言,因此不可以将非布尔值来代替布尔值。

let i = 1
if i {
    //编译时会报错
}
let i = 1
if i == 1 {
    // 会成功编译
}

元组

元组是Swift中新增的概念,是将多个值合成一个单一的值。元组中的各个值不必是相同类型。

let http404Error = (404, "Not Found")
//http404Error是(Int, String)类型
访问元组
  • 将元组中的内容分解为独立的常量/变量,然后按通常的方式来访问:
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"
  • 前提:定义元组时,为元组中的单个元素命名。可以使用元素名称来访问元组中的元素:
print("The status code is \(http200Status.statusCode)")
//输出: "The status code is 200"
print("The status message is \(http200Status.description)")
//输出: "The status message is OK"
总结:
  • 元组在作为函数返回值时,是非常有用的。
  • 元组不适用于创建复杂的数据结构,它仅对多个相关值临时组合在一起是有用的。

可选类型

Swift中新增的概念。如果一个值有可能不存在,那么就使用可选类型。一个可选类型包括两种可能性:一是有值,你需要解包来访问这个值。二是压根就无值。

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
//convertedNumber被推断为"Int?",或可选Int类型

因为Int()初始化方法有肯呢个失败,所以它返回的是可选的Int类型,写成Int?。使用问号(?)来指定它包含的值是可选的。

nil

nil指定一个常量/变量不包含任何值。

var serverResponseCode: Int? = 404
// serverResponseCode 包含一个实际的值404
serverResponseCode = nil
// serverResponseCode 此时不包含任何值

如果定义一个未提供默认值的可选变量,这个可选变量会被自动设置为nil

var surveyAnswer: String?
// surveyAnswer 被自动设置为nil
if语句和强制解包

通过将可选值同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."
可选绑定

使用可选绑定来确认可选变量/常量是否包含一个值,如果包含,将其赋值给一个临时的常量/变量。

if let constantName = someOptional {
    statements
}
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"

可以在条件语句中使用任意多个可选绑定和Bool值,使用逗号(,)分隔。如果任意的可选绑定是nil或任意的布尔值是false,则整个条件语句为false。

if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
    print("\(firstNumber) < \(secondNumber) < 100")
}
//输出: "4 < 42 < 100"

if let firstNumber = Int("4") {
    if let secondNumber = Int("42") {
        if firstNumber < secondNumber && secondNumber < 100 {
            print("\(firstNumber) < \(secondNumber) < 100")
        }
    }
}
//输出: "4 < 42 < 100"
隐式解包的可选类型

直接看例子:

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! 
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString 

使用隐式解包的前提是:确定该可选变量/常量有值。定义时,在类型后面加!来指定该变量/常量已隐式解包,后面如果在使用这个变量/常量就不用在强制解包了。

总结:
  • Swift中的nil和Objective-C中的nil不同,Swift中的nil不是一个指针,它只代表特定类型的缺失值,任何类型都可以被设置为nil。
  • 如果在不存在的可选值后使用!,会造成运行时错误。
  • 在if和while语句中使用可选绑定。

错误处理

使用错误处理来响应程序执行过程中可能遇见的错误条件。

  • 抛出错误,通过throws关键字:
func canThrowAnError() throws {
    // 这个函数有可能会抛出一个错误
}
  • 捕获错误,通过catch关键字:
do {
    try canThrowAnError()
    // no error was thrown
} catch {
    // an error was thrown
}
  • 错误的处理流程:
func makeASandwich() throws {
    // ...
}

do {
    try makeASandwich()
    eatASandwich()
} catch SandwichError.outOfCleanDishes {
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
}

断言

在某些情况下,如果不满足某个条件,程序就不能执行下去,这时候可以使用断言来终止程序的执行并调试。

什么时候使用断言

如果条件有可能是false,但要求必须是true,这时候使用断言。断言检测的场景包括:

  • 索引越界。
  • 无效的函数参数。
  • 一个可选类型必须有值的时候才能继续执行。
总结:
  • 断言是发现程序中不合法值的一种有效方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值