博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Swift3.0P1 语法指南——基础
阅读量:5901 次
发布时间:2019-06-19

本文共 10861 字,大约阅读时间需要 36 分钟。

原档:

-----------------------------------------2016/07/01 3.0preview1版本----------------------------------

一、常量与变量

1、声明

let maximumNumberOfLoginAttempts = 10 var currentLoginAttempt = 0

声明一个名为maximumNumberOfLoginAttempts的常量,赋值为10。

声明一个名为currentLoginAttempt的变量,初始化值为0。

也可以在同一行中声明多个变量:

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

注:如果在代码中,某个存储的数据量不会再发生变化,则总是把这个量用let关键字声明为常量。只用变量来表示那些需要改变值的量。

2、类型标注

1 var welcomeMessage: String2 var red, green, blue: Double

Swift可以根据赋的初值来推断出变量或常量的类型。当你没有赋予初值的时候,则务必要声明变量或常量的类型。

3、命名

常量和变量的名字几乎可以包含任何字符,包括Unicode字符:

1 let π = 3.141592 let 你好 = "你好世界"3 let ?? = "dogcow"

但不能包含空格、数学符号、箭头、私用(或无效)的Unicode代码、绘图符号或制表符。也不能以数字开头。

一旦成功声明一个变量或常量,就不能再更改它的类型。

注:如果你需要使用与Swift保留关键字相同的名称作为常量或者变量名,你可以使用反引号(`)将关键字包围的方式将其作为名字使用。当然,你应当避免使用关键字作为常量或变量名,除非你真的别无选择。

4、打印

1 print(friendlyWelcome)2 // prints "Bonjour!"

用print(_:separator:terminator:)这个方法来打印常量或变量。这是一个可以打印一个或多个值的全局函数,separator和terminator有默认的值,使用的时候可以省略。默认情况下,打印输出的内容会在最后换行。如果不想换行,可以将空的字符串传递给terminator,例如:

1 print(someValue, terminator: "")

Swift用字符串插入将常量或变量名作为占位符,来打印出复杂的信息。

1 print("The current value of friendlyWelcome is \(friendlyWelcome)")2 // prints "The current value of friendlyWelcome is Bonjour!"

二、注释

单行注释:

1 // this is a comment

多行注释:

1 /* this is also a comment,2 but written over multiple lines */

不同于C语言,Swift中的多行注释可以嵌套:

1 /* this is the start of the first multiline comment2     /* this is the second, nested multiline comment */3 this is the end of the first multiline comment */

三、分号

1 let cat = "?"; print(cat)2 // prints "?"

Swift不需要在每一句表达式后面加分号,但是如果同一行有多个表达式,则需要分号来分隔。

四、整型

1、范围

 可以通过min或max属性来访问每一种整型数据的最小值或最大值。

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

2、Int和UInt

大多数情况下,你不必使用指定长度的整型变量。使用Int即可。当然,也可以用无符号的UInt。

在32位系统中,Int相当于Int32,UInt相当于UInt32。

在64位系统中,Int相当于Int64,UInt相当于UInt64。

注意:尽量不要使用UInt,除非你真的需要存储一个和当前平台原生字长相同的无符号整数。除了这种情况,最好使用Int,即使你要存储的值已知是非负的。统一使用Int可提高代码的可复用性,避免不同整型数据之间的转换,并且匹配整型的类型推测。

五、浮点型

Double表示64位的浮点数

Float表示32位的浮点数

类型推断时,浮点数默认被推断为Double类型。

Double类型有至少15个小数位的精确度,而Float类型则有6个小数为的精确度。

六、类型安全和类型推断

 Swift是一种类型安全的语言,如果声明变量或常量时没有指定类型,则Swift会根据值推断出变量或常量的类型。

1 let meaningOfLife = 422 // meaningOfLife is inferred to be of type Int3 let pi = 3.141594 // pi is inferred to be of type Double5 let anotherPi = 3 + 0.141596 // anotherPi is also inferred to be of type Double

七、数值型字面量

十进制没有前缀,二进制前缀为0b,八进制前缀为0o,十六进制前缀为0x。

1 let decimalInteger = 172 let binaryInteger = 0b10001       // 17 in binary notation3 let octalInteger = 0o21           // 17 in octal notation4 let hexadecimalInteger = 0x11     // 17 in hexadecimal notation

浮点数可以是十进制或者十六进制。

十进制的浮点数以大写或小写的e来指定指数,基数为10. 

1.25e2 means 1.25 x 102, or 125.0.

1.25e-2 means 1.25 x 10-2, or 0.0125.

十六进制的浮点数以大写或小写的p来指定指数,基数为2。

0xFp2 means 15 x 22, or 60.0.

0xFp-2 means 15 x 2-2, or 3.75.

下面的浮点字面值都等于十进制的12.1875

1 let decimalDouble = 12.18752 let exponentDouble = 1.21875e13 let hexadecimalDouble = 0xC.3p0

数值型字面值可以加上多余的0和下划线_来增加数字的可读性。

1 let paddedDouble = 000123.4562 let oneMillion = 1_000_0003 let justOverOneMillion = 1_000_000.000_000_1

八、数值型类型转换

通常情况下只用默认的整型Int,只有在一些特殊的情况下才使用其他整型,比如处理来自外部的指定长度的数据、或者为了性能或内存占用或其他必要的优化。使用显式指定长度的类型可以及时发现值溢出并且可以暗示正在处理特殊数据。

1、整型之间的转换

不同整数类型的变量和常量可以存储不同范围的数字,如果存储的数字超出了该类型的范围,编译时就会报错。

let cannotBeNegative: UInt8 = -1// UInt8 cannot store negative numbers, and so this will report an errorlet tooBig: Int8 = Int8.max + 1// Int8 cannot store a number larger than its maximum value,// and so this will also report an error

必须根据不同情况选择性使用数值型类型转换,这种选择性的方式,可以预防隐式转换的错误并让你的代码中的类型转换意图变得清晰。

要将一种数字类型转换成另一种,你要用当前值来初始化一个期望类型的新数字,这个数字的类型就是你的目标类型。如下,用one的值来初始化一个UInt16的整型,并将其与twoThousand相加。

1  twoThousand: UInt16 = 2_0002  let one: UInt8 = 13  let twoThousandAndOne = twoThousand + UInt16(one)

SomeType(ofInitialValue)是一个调用 Swift 构造器并传入一个初始值的默认方法。在语言内部,UInt16有一个构造器,可以接受一个UInt8类型的值,所以这个构造器可以用现有的UInt8来创建一个新的UInt16。注意,你并不能传入任意类型的值,只能传入UInt16内部有对应构造器的值。不过你可以扩展现有的类型来让它可以接收其他类型的值(包括自定义类型)

2、整型和浮点之间的转换

整型转浮点数:

1 let three = 32 let pointOneFourOneFiveNine = 0.141593 let pi = Double(three) + pointOneFourOneFiveNine4 // pi equals 3.14159, and is inferred to be of type Double

浮点数转整型:

1 let integerPi = Int(pi)2 // integerPi equals 3, and is inferred to be of type Int

当用这种方式来初始化一个新的整数值时,浮点值会被截断。也就是说4.75会变成4,-3.9会变成-3。

注意:结合数字类常量和变量不同于结合数字类字面量。字面量3可以直接和字面量0.14159相加,因为数字字面量本身没有明确的类型。它们的类型只在编译器需要求值的时候被推测。

九、类型别名

 当你想要给现有类型起一个更有意义的名字时,类型别名非常有用。例如正在处理特定长度的外部资源的数据:

1 typealias AudioSample = UInt162 var maxAmplitudeFound = AudioSample.min3 // maxAmplitudeFound is now 0

十、布尔型

1 let orangesAreOrange = true2 let turnipsAreDelicious = false3 if turnipsAreDelicious {4     print("Mmm, tasty turnips!")5 } else {6     print("Eww, turnips are horrible.")7 }8 // prints "Eww, turnips are horrible."

如果你在需要使用Bool类型的地方使用了非布尔值,Swift 的类型安全机制会报错:

1 let i = 12 if i {3     // this example will compile successfully4 }

这样才是合法的:

1 let i = 12 if i == 1 {3     // this example will compile successfully4 }

十一、元组

元组(tuples)把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型,可以把任意顺序的类型组合成一个元组。

1 let http404Error = (404, "Not Found")2 // http404Error is of type (Int, String), and equals (404, "Not Found")

(404, "Not Found")元组把一个Int值和一个String值组合起来表示 HTTP 状态码的两个部分:一个数字和一个人类可读的描述。

元组内容分解:

1 let (statusCode, statusMessage) = http404Error2 print("The status code is \(statusCode)")3 // prints "The status code is 404"4 print("The status message is \(statusMessage)")5 // prints "The status message is Not Found"

可以用下划线忽略某些元素的值:

1 let (justTheStatusCode, _) = http404Error2 print("The status code is \(justTheStatusCode)")3 // prints "The status code is 404"

还可以通过下标来访问单个元素:

1 print("The status code is \(http404Error.0)")2 // prints "The status code is 404"3 print("The status message is \(http404Error.1)")4 // prints "The status message is Not Found"

可以在声明元组时给各个元素命名:

1 let http200Status = (statusCode: 200, description: "OK")

给元素命名后,可以通过元素名来访问元素的值:

1 print("The status code is \(http200Status.statusCode)")2 // prints "The status code is 200"3 print("The status message is \(http200Status.description)")4 // prints "The status message is OK"

 元组作为函数的返回值时,非常有用。

注意:元组在临时组织值的时候很有用,但是并不适合创建复杂的数据结构。如果你的数据结构并不是临时使用,请使用类或者结构体而不是元组。

 十二:可选型

1、可选

使用可选(optionals)来处理值可能缺失的情况。

一个可选值是指:有值,值为x,或者没有值。

注意:C 和 Objective-C 中并没有可选这个概念。最接近的是 Objective-C 中的一个特性,一个方法要不返回一个对象要不返回nil,nil表示“缺少一个合法的对象”。然而,这只对对象起作用——对于结构体,基本的 C 类型或者枚举类型不起作用。对于这些类型,Objective-C 方法一般会返回一个特殊值(比如NSNotFound)来暗示值缺失。这种方法假设方法的调用者知道并记得对特殊值进行判断。然而,Swift 的可选可以让你暗示任意类型的值缺失,并不需要一个特殊值。

1 let possibleNumber = "123"2 let convertedNumber = Int(possibleNumber)3 // convertedNumber is inferred to be of type "Int?", or "optional Int"

上例中,Int初始化器可能失败,因为字符串可能不能转化为数字,所以convertedNumber被推断为Int?型,它可能有一个Int值,也可能没有值。

2、nil

可以通过赋值nil使可选值变成没有值的状态:

1 var serverResponseCode: Int? = 4042 // serverResponseCode contains an actual Int value of 4043 serverResponseCode = nil4 // serverResponseCode now contains no value

注意:nil不能赋给不可选的常量或变量,如果变量的值存在没有值的情况,那就将其声明为可选型。

如果没有赋初值,则可选型默认初值为nil。

1 var surveyAnswer: String?2 // surveyAnswer is automatically set to nil

注意:Swift的nil不同于Objective-C的nil。在Objective-C中,nil是一个不存在的对象的指针。在Swift中,nil不是一个指针,它是某种类型的缺失值,不只是对象,任意类型的可选值都可以赋值为nil。

3、if 语句以及强制解包

 可以使用if语句来判断一个可选是否包含值

1 if convertedNumber != nil {2     print("convertedNumber contains some integer value.")3 }4 // prints "convertedNumber contains some integer value."

如果确定可选包确实含值,你可以在可选的名字后面加一个感叹号(!)来获取值。这个惊叹号表示“我知道这个可选有值,请使用它。”这被称为可选值的强制解析(forced unwrapping):

1 if convertedNumber != nil {2     print("convertedNumber has an integer value of \(convertedNumber!).")3 }4 // prints "convertedNumber has an integer value of 123."

注意:使用!来获取一个不存在的可选值会导致运行时错误。使用!来强制解析值之前,一定要确定可选包含一个非nil的值。

4、可选绑定

使用可选绑定(optional binding)来判断可选是否有值,如果有,就把值赋给一个临时常量或者变量。可选绑定可以用在if和while语句中来对可选的值进行判断并把值赋给一个常量或者变量。

1 if let actualNumber = Int(possibleNumber) {2     print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")3 } else {4     print("\'\(possibleNumber)\' could not be converted to an integer")5 }6 // prints "'123' has an integer value of 123"

“如果Int(possibleNumber)返回的可选Int包含一个值,创建一个叫做actualNumber的新常量并将可选包含的值赋给它。”

可以在可选绑定中使用常量和变量。如果你想在if语句的第一个分支中操作actualNumber的值,你可以改成if var actualNumber,这样可选包含的值就会被赋给一个变量。

也可以在一个if语句中包含多个可选绑定,并用where字句来检查判断条件的布尔值:

if let firstNumber = Int("4"), secondNumber = Int("42") where firstNumber < secondNumber {    print("\(firstNumber) < \(secondNumber)")}// prints "4 < 42"

5、隐式解析可选

有时候在程序架构中,第一次被赋值之后,可以确定一个可选总会有值。在这种情况下,每次都要判断和解析可选值是非常低效的,因为可以确定它总会有值。

这种类型的可选被定义为隐式解析可选(implicitly unwrapped optionals)。把想要用作可选的类型的后面的问号(String?)改成感叹号(String!)来声明一个隐式解析可选。

一个隐式解析可选其实就是一个普通的可选,但是可以被当做非可选来使用,并不需要每次都使用解析来获取可选值。

let possibleString: String? = "An optional string."let forcedString: String = possibleString! // requires an exclamation mark let assumedString: String! = "An implicitly unwrapped optional string."let implicitString: String = assumedString // no need for an exclamation mark

可以把隐式解析可选当做一个可以自动解析的可选。只是声明的时候把感叹号放到类型的结尾,而不是每次取值的可选名字的结尾。

注意:如果在隐式解析可选没有值的时候尝试取值,会触发运行时错误。和在没有值的普通可选后面加一个惊叹号一样。

可以把隐式解析可选当做普通可选来判断它是否包含值,

if assumedString != nil {   print(assumedString)}// Prints "An implicitly unwrapped optional string."

也可以在可选绑定中使用隐式解析可选来检查并解析它的值。

if let definiteString = assumedString {   print(definiteString)}// Prints "An implicitly unwrapped optional string."

注意:如果一个变量之后可能变成nil的话请不要使用隐式解析可选。如果你需要在变量的生命周期中判断是否是nil的话,请使用普通可选类型。

十三、错误处理

使用错误处理来响应程序运行中可能发生错误的情况。

与可选相比,可选可以用它的值是否存在来表示函数运行成功或失败,而错误处理则使得你可以判断造成失败的原因,必要时,可以将错误传给程序的其他部分来处理。

当函数运行失败,它抛出一个错误。函数的调用者则可以获取这个错误并进行响应:

1 func canThrowAnError() throws {2     // this function may or may not throw an error3 }

Swift自动将错误抛出当前范围,除非在这里被catch语句处理。

1 do {2     try canThrowAnError()3     // no error was thrown4 } catch {5     // an error was thrown6 }

允许错误传递给多个catch语句:

1 func makeASandwich() throws { 2     // ... 3 } 4   5 do { 6     try makeASandwich() 7     eatASandwich() 8 } catch Error.OutOfCleanDishes { 9     washDishes()10 } catch Error.MissingIngredients(let ingredients) {11     buyGroceries(ingredients)12 }

十四、断言

可选可以让你判断值是否存在,你可以在代码中优雅地处理值缺失的情况。然而,在某些情况下,如果值缺失或者值并不满足特定的条件,你的代码可能并不需要继续执行。这时,你可以在你的代码中触发一个断言(assertion)来结束代码运行并通过调试来找到值缺失的原因。

1、用断言进行调试

断言会在运行时判断一个逻辑条件是否为true。从字面意思来说,断言“断言”一个条件是否为真。你可以使用断言来保证在运行其他代码之前,某些重要的条件已经被满足。如果条件判断为true,代码运行会继续进行;如果条件判断为false,代码运行停止,你的应用被终止。

可以使用全局assert函数来写一个断言。向assert函数传入一个结果为true或者false的表达式以及一条信息,当表达式为false的时候这条信息会被显示:

1 let age = -32 assert(age >= 0, "A person's age cannot be less than zero")3 // this causes the assertion to trigger, because age is not >= 0

断言中的信息也可以省略:

assert(age >= 0)

注意:当你的代码使用最优编译时,断言是无效的,例如使用XCode的默认Release版本来构建app时。

2、什么时候使用断言

当条件可能为假时使用断言,但是最终一定要保证条件为真,这样你的代码才能继续运行。断言的适用情景: 

- 整数的附属脚本索引被传入一个自定义附属脚本实现,但是下标索引值可能太小或者太大。

- 需要给函数传入一个值,但是非法的值可能导致函数不能正常执行。

- 一个可选值现在是nil,但是后面的代码运行需要一个非nil值。

注意:断言可能导致应用终止运行,所以应当仔细设计你的代码来让非法条件不会出现。当然,在你的应用发布之前,有时候非法条件可能出现,这时使用断言可以快速发现问题。

转载于:https://www.cnblogs.com/tt2015-sz/p/4860071.html

你可能感兴趣的文章
Python3.7.1学习(六)RabbitMQ在Windows环境下的安装
查看>>
Windows下memcached的安装配置
查看>>
ubuntu: firefox+flashplay
查看>>
web.xml 中CharacterEncodingFilter类的学习
查看>>
贪吃蛇逻辑代码
查看>>
实现c协程
查看>>
ASP.NET视频教程 手把手教你做企业论坛网站 视频教程
查看>>
[LeetCode] Meeting Rooms II
查看>>
从Swift学习iOS开发的路线指引
查看>>
Scribes:小型文本编辑器,支持远程编辑
查看>>
ssh 安装笔记
查看>>
3-继承
查看>>
海归千千万 为何再无钱学森
查看>>
vue2.0 仿手机新闻站(六)详情页制作
查看>>
JSP----九大内置对象
查看>>
Java中HashMap详解
查看>>
delphi基本语法
查看>>
沙盒目录介绍
查看>>
260. Single Number III
查看>>
Hadoop生态圈-Kafka的完全分布式部署
查看>>