Swift 教程 (一)—基础部分、基本运算符

784 阅读10分钟
原文链接: ppsheep.com

Swift 该来的还是要来的,Swift使用范围越来越广,你不用,大家都会用,然后呢。。。你又落后了。。

常量变量

首先呢,每门语言都是从常量变量讲起,Swift当然也不例外

在Swift中常量 使用 let声明 变量使用var声明
不像OC或者Java 我们在声明常量变量时,可以不加类型,编译器能够帮助我们推断出类型,像这样

let myName = "Yang Qian"
var myAge = 23

在上面两行中,并没有指明 myAge 和 myName 的类型,编译器也没有报错,当然,我们也是可以声明他们的类型的:

let myName: String = "Yang Qian"
let myAge: Int  = 23
let 🐶🐮 = "dogcow"

注意这里有一个书写规范,苹果在文档中特意提醒了,在声明类型的时候,需要在冒号后面空一格,保持格式一致。

常量(let)一旦声明,便不可更改。变量(var)可进行更改

注释

// This is a comment. 这是一行注释
/*
 这是多行注释
 */

分号

关于分号呢,在Swift中,每个语句结束是不用写分号的,当然也可以写,但是我们推荐呢,还是不要写了,苹果都说不用写了,你还写干嘛,而且现在看一些开源的Swift代码,大神都没写分号。

但是存在一种情况,就是如果你想在一行写多个语句,那每个语句之间你就需要用分号隔开了

//这样就会报错了
let myName: String = "Yang Qian" let myAge: Int  = 23
//要这样写
let myName: String = "Yang Qian" ; let myAge: Int  = 23

这样的代码也太丑了吧,还是一行一个语句吧,养成良好的代码习惯

整数Int

在Swift上,提供了一个特殊的整数类型Int,在32位的机器上运行,那这个整数的长度就是和Int32相同,如果实在64为机器上运行,那这个整数的长度就是Int64的,一般来说 我们直接使用Int就已经OK了。

无类型UInt

无符号类型,一般呢我们不使用,为什么呢? 苹果文档上讲的

Use UInt only when you specifically need an unsigned integer type with the same size as the platform’s native word size. If this is not the case, Int is preferred, even when the values to be stored are known to be non-negative

类型别名

类型别名 就是给现有的类型加上一个我们自己自定义的名称 使用关键字 typealias定义

//这样,我们就将UInt16定义成了 AudioSample
typealias AudioSample = UInt16
var maxAmplitudeFound = AudioSample.min
// 等价于  var maxAmplitudeFound = UInt16.min

Booleans

现在我们的布尔值 不再是OC 中的 Yes 和 No 了 需要使用 true false

而且 现在呢,我们也不能再使用int的 0 1 来表示 true 或者false 了 之前呢 OC是可以这样使用的 但是在swift中,编译器就会报错了

let i = 1
if i {
    // this example will not compile, and will report an error
}

这样,苹果讲了,是会报错的

Tuples 元组

元组,这个厉害了,这个可以把多个值组合成一个复合值,就是一个元组,而且这个元组里的各个值,不用类型相同,这下厉害了,这样一来,我们传参数,还有函数返回值,都可以多个了 想想 挺激动的 虽然还没用

let http404Error = (404, "Not Found")

上面,就是一个表示404 的一个元组,看到了,是一个404 Int 和 一个 String

let http404Code = (404, "Not Found")
let (statusCode, statusString) = http404Code
print("the code is \(statusCode)")
print("the message is \(statusString)")

输出:

the code is 404
the message is Not Found

如果呢,我们只关心我们需要的数据,不关心其他的,比如在上面的例子中,我们只关心code 那么我们就可以这样写

let http404Code = (404, "Not Found")
let (statusCode, _) = http404Code
print("the code is \(statusCode)")
//print("the message is \(statusString)")

输出

the code is 404

能少写一点是一点

还可以呢,像数组一样,输出元组的第几位:

let http404Code = (404, "Not Found")
print("the code is \(http404Code.0)")
print("the message is \(http404Code.1)")

输出呢,一样的:

the code is 404
the message is Not Found

别急 还有写法呢:

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

然后我们来输出:

print("The status code is \(http200Status.statusCode)")
// Prints "The status code is 200

简直太强大了,我个人最喜欢 那种点语法

Optionals 可选类型

使用可选类型,用来处理值可能缺失的情况,这样一来,我们的代码安全性能够提升很多

一般来说,这个可选类型就两种情况

  • 有值 就是x
  • 无值 就是nil

我们知道在OC中,是没有这个概念的,在OC中,比如我们有一个方法,有返回值,如果是返回的是对象,要么就是返回对象实例,要么返回nil表示值缺失。但是我们遇到需要返回枚举,我们就没办法了,一般我们会定义一个NotFound这种类型,但是在Swift我们就不需要了

我们举个例子

如果我们想讲一个字符串,强转成一个Int整形,我们知道,不可能每个字符串都能转成整数,像”123”这种可以转成整形,但是”ni hao”这种,能转成整形吗?你在逗我

let testString = "123"
let testString1 = "ni hao"
let testInt1 = Int(testString1)
let testInt2 = Int(testString)

这样代码并不会报错

我们可以手动来设置optional值

var serverResponseCode: Int? = 404
// serverResponseCode contains an actual Int value of 404
serverResponseCode = nil
// serverResponseCode now contains no value

注意,在Swift中,nil的定义和Objective-C中的nil定义不相同,在Swift中,nil只是用来表示值缺失,不管是对象,还是Int之类的基础类型,都可以使用nil来表示值缺失,但是在OC中就只有对象可以使用,因为在OC中是表示一个指向不存在对象的指针

如果你像下面这样定义了一个变量,不需要你声明他为nil,编译器会自动为他赋值nil,这根OC中 还是有较大的差别的

var surveyAnswer: String?

同样的,我们还是和OC一样,可以使用==或者!=来判断是否是nil

if surveyAnswer != nil{
    //做什么
}

如果,我们能够确定,这个变量,肯定是有值的,那么我们就可以使用强制解包,在其后面加上一个!

像这样

if surveyAnswer != nil{
    //我们已经知道surveyAnswer是肯定有值的
    print(surveyAnswer!)//强制解包 输出
}

在我们强制解包的时候,一定要确保这个值是有的,不然,会出现错误,导致程序崩溃

可选绑定

这个 厉害了,很好用的

我们可以在if 和 while 语句中使用 我就直接上代码了

if let actualNumber = Int(possibleNumber) {    print("\"\(possibleNumber)\" has an integer value of \(actualNumber)")} else {    print("\"\(possibleNumber)\" could not be converted to an integer")}// Prints ""123" has an integer value of 123”

我们上面讲过,这个强转,转出来是一个optional值,我们在if语句中判断这个值,如果存在,则将这个值赋给actualNumber常量,在判断语句中需要使用到,如果转出来是一个nil,那么就跳到另外的语句中

还有更强大的

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

这么强大 的 if语句

隐式解析

有时候,我们很确定,一些变量或者常量,肯定是有值的,不需要声明为optional,不然我们每次使用的时候,都需要加上!来进行解包

Swift为我们提供了隐式声明

let absolutString: String! = "我肯定是有值的"
print(absolutString)//可以直接使用,不需要解包

错误处理

如果之前有写过Java的同学肯定对try catch很熟悉 在Swift中,使用try catch来进行错误的捕获和处理

func makeASandwich() throws {
    // 这个函数可能会抛出错误异常
}
 
do {
    try makeASandwich()//开始做三明治
    eatASandwich()//开始吃三明治
} catch SandwichError.outOfCleanDishes {//这里捕获到了异常,没有干净的盘子
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {//又捕获到了异常,没有原材料
    buyGroceries(ingredients)//买原材料
}

断言

断言是很好用的一个东西,而且鼓励大家使用断言。

断言是什么意思呢?就是我们在运行一个函数时,有事我们需要某个参数,比如一个Int一定要是一个大于0的数,如果不大于0,我们的函数就无法运行了,这时候,我们就可以使用断言了

let age = -3
assert(age >= 0, "A person's age cannot be less than zero")

这样程序就会检查age是否是大于等于0 的 如果不符合,程序就会终止,并且我们能够很快知道 为什么程序会终止

那我们什么时候需要用到断言呢?

  • 当传入一个int的下标时,比如传入数组的索引,这个整数的值可能会太大或者太小
  • 需要给函数传入一个值,但是非法的值可能导致函数不能正常执行。
  • 一个可选值现在是nil,但是后面的代码运行需要一个非nil值

赋值操作

很简单,就是一个加号

let a = 10
let b = 5
b = a
print(b)
//b输出 10

元组赋值

let (x,y) = (1,2)
//好了赋值好了 x = 1 y = 2

基本运算

加减乘除我就不讲了吧

这里有一个还是要讲一下,字符串的加法 这个在Swift中是特有的

let a = "我是"
let b = "程序员"
let c = a + b
print(c)
//我是程序员

取余运算

9%2 = 1  等价于  (4*2)+1  余下一个1
-9%2 = -1 等价于  (-4*2)+ -1  余下一个 -1

负号的使用

负负得正 这个我们都知道的哦

let a = -1
let b = -a
//b现在是1
let c = -b
//现在c是-1

+=使用

这个 大家也在其他的语言中见过

let a = 10
a+=2  //a = a+2
print(a)//输出12

但是需要注意的是 我们没有这样的用法

let b = a+=2 //这种用法是错误的

比较运算符

== 等于

!= 不等于

>

<

>=

<=

这里还有一个字符串的比较

let a = "world"
let b = "world"
if a == b {
    //这里是能够执行到的  这为真, 这里需要注意下
}

元组的比较

(2,"abc")>(1,"bca")  //2>1  
(1,"abc")<(1,"bca")  //1相同 比较abc和bca 先比较第一个字母  
(1,"abc") == (1,"abc")

三目运算

let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
// rowHeight is equal to 90

空合运算

这个空合运算时针对值为nil的时候来做的

let defaultColorName = "red"
var userDefinedColorName: String?   // defaults to nil
 
var colorNameToUse = userDefinedColorName ?? defaultColorName

这里如果userDefinedColorName不是nil的话colorNameToUse的值就是userDefinedColorName的值,如果userDefinedColorName是nil 那么colorNameToUse的值,就是defaultColorName的值

区间运算符

闭合运算,包含两端

for index in 1...5 {
    print("\(index) times 5 is \(index * 5)")
}
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
// 4 times 5 is 20
// 5 times 5 is 25

半开合运算 包含左端 不包含右端

let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..

逻辑运算

逻辑运算 包括

!非
&& 且
|| 或

基础的运算符完成了,接下来我们就开始学习String了