Swift快速入门(一)之 Swift基础语法

近期重新学习了一遍Swift语言,主要以《Swift编程权威指南(第2版)》为教程,学习过程中结合比对Java语言特性将学习心得作为三篇笔记:Swift基础语法,Swift面向对象编程,Swift高级编程。

本文为第一篇《Swift基础语法》主要涵盖以下内容

  • 类型、常量和变量
  • if-else条件语句
  • switch语句
  • 数 整数和浮点数
  • 循环 for和while
  • 字符串
  • 可空类型
  • 数组 Array
  • 集合 Set
  • 字典 Dictionary

类型、常量和变量

//常量的声明 let
//声明一个Int常量,常量一旦声明后不可变化
let num:Int = 2019
print(num)

//变量的声明 var
//声明一个字符串变量:声明一个名为name的变量,其类型是String,初始值是”Tom“
var name:String = "Tom"

//总结:对必须变化的实例用变量,其他都用常量

//Switf支持类型推断:声明变量或常量时无需声明类型,编译器会根据初始值内容进行推断
let n = 2019  //根据2019内容自行推断 实例n的类型为Int
let firstName = "Nik"
var lastName = "Lily"
print(n)

Swift中数 分为 整数和浮点数

  1. 整数: Int 64位
  2. 浮点数:Float 32位,Double 64位
  3. 整数操作符
  4. 加减乘除:+、—、*、/
  5. 取余: %
    ```swift
    //1. 整数类型的变量的声明
    var i1:Int = 10
    var f1:Float = 10.0 //32位
    var d1:Double = 10.0 //64位

//2. 类型转换
// Java中两个不同精度的数值相加会自动转换为较高精度,但Swift中需要手动转换类型使之匹配
//let number = i1 + f1 //不同类型数据相加 在swift中会异常
let number = Double(i1) + d1
print(str)
print(number)

//3. 浮点数
//浮点数:Float 32位,Double 64位
//浮点数默认的类型推断是 Double
let n2 = 1.98
print(type(of: n2)) //输出结果 Double


## 条件语句
#### if-else 由特定的条件逻辑执行代码,通常要处理一个非此即彼的状况
```swift
let age = 18
if age > 18{
    print("成年人")
}else
{
    print("未成年人")
}


if-else if 的使用


let age = 58
if age <= 18{
    print("未成年人")
}else if age<55
{
    print("青壮年")
}else
{
    print("老年人")
}


if-else 嵌套语句


let age = 88
if age > 18{
    if age>60{  //
        print("老年人")
    }else
    {
        print("成年人")
    }
}else
{
    print("未成年人")
}


三目运算 :理解为简化版 if-else使用

a?b:c “如果a为真,则执行b;否则执行c”


let age = 20
var result = age > 18 ? "成年人" : "未成年人";
print(result)


逻辑运算符


&& 逻辑与:当且仅当两者都为真时结果为真
|| 逻辑或:两者任意之一为真结果为真
! 逻辑非:真变假,假变真


switch语句:用于处理多重条件的情况

区别:if else用于处理”非此即彼“的情况,swith用于处理多重条件的情况

ps:先上结论

switch语句特性

  1. 每个case分支后不需要break
  2. swift语句中 default分支不是必需的
  3. fallthrough 状态转移语句,会先执行自己分支代码后,再把控制权转移到下面紧挨着的分支
  4. case 匹配值 支持区间 如 case 1…100 表示 1到100的区间内
  5. case 匹配值可支持 多个
  6. case 匹配值可使用where条件子句

swith 使用汇总


var code = 401
var erroInfo:String = "erro code is:"
switch code {
case 200,201,202:
    print("Http success ")
case 300...399:  //...区间
    print("300系列错误")
case let code where (code >= 400 && code <= 499) :  //where语句的使用,筛选条件
    erroInfo += "(code) 400系列错误"
//    fallthrough //不需要匹配进入下一个分支并执行代码
default:
    erroInfo += "(code)"  //字符串插值
    print("其他错误")
}


关于switch语法使用一一道来

switch语句


var httpcode=400
switch  httpcode{
case 200:
    print(httpcode)
case 400:
    print(httpcode)
default:
    print("default")
}


switch分支可以使用多个值


var httpcode=400
switch  httpcode{
case 200:
    print(httpcode)
case 400,401,402:
    print("服务器异常")
default:
    print("default")
}


switch可以是一个值,多个值,区间


var httpcode=322
switch  httpcode{
case 200:
    print(httpcode)
case 300...399:
    print(httpcode)
case 400,401,402:
    print("服务器异常")
default:
    print("default")
}


值绑定(字符串插值)占位符


var httpcode=322
var resultstr=""
switch  httpcode{
case 200:
    resultstr="OK"
case 300...309:
    resultstr="redirect:(httpcode)"
case 400,401,402:
    resultstr="client erro:(httpcode)"
case let unkwnowncode:
    resultstr="(unkwnowncode) is not known erro code"
}


default 语句(不是必需的)


var httpcode=800
switch  httpcode{
case 200:
    print(httpcode)
case 300...399:
    print(httpcode)
case 400,401,402:
    print("服务器异常")
default:
    print("default httpcode:(httpcode)")  
}


用where语句创建筛选条件


var httpcode:Int = 205
switch  httpcode{
case 200:
    print(httpcode)
case 300...399:
    print(httpcode)
case 400,401,402:
    print("服务器异常")
case let unknowcode where (unknowcode>201 && unknowcode<208): //指定httpcode 范围
    print("unknowcode where httpcode:(httpcode)")   //where
default:
        print("default httpcode:(httpcode)") 
}


元组和模式匹配

元组是把具有逻辑关联的两个或多个变量的组合,组合的结果是一个有序列表


var httpCode=200
var msg="message:"
switch httpCode{
case 200:
    msg+="成功"
case 300...399:
    msg+="重定向"
case 400,401,402:
    msg+="服务器错误"
default:
    msg+="未知"
}
let erro=(httpCode,msg)
//访问元组
erro.0
erro.1  //通过序号访问元组元素
//1.9给元组的元素别名
let erro2=(code:httpCode,erroInfo:msg)
erro2.code
erro2.erroInfo


用元组做模式匹配


var firstCode:Int=201
var secondCode:Int=404
let erro=(firstCode,secondCode)
switch  erro{
case (201,400):
    print("201,400")
case (200,_):
    print("200,_")
case (_,404):
    print("_,404")
default :
    print("default")
}


switch 和 if-else


var age=23
switch  age{
case 18...28:
    print("年轻人")
default:
    print("age =:(age)")   //default 语句
}
//使用if-case替代,不需要写不关注的default分支,更关注核心代码逻辑
var age=23
if case 18...28=age{
        print("年轻人")
}

var age=26
if case 18...28=age,age>25{
    print("大于25岁的年轻人")
}


循环

  • for循环
  • while 循环

for-in 循环的用法


var number:Int = 0;
for i in 1...5{  //遍历 1至5
//    print(i)
    number += 1
    print(number)
}


不需要迭代器i的用法


for _ in 1...5
{
    number += 1
    print(number)
}


带where语句的for-in循环


for i in 1...10 where i % 3 == 0
{
    print(" 能被3整除的数:(i)")
}


while循环的使用


var number:Int = 3
while number > 0 {
    print(" while 循环 (number)")
    number -= 1;
}


repeat-while 循环,相当于java中的 do-while循环


repeat{
    print(number)
    number += 1
}while number <= 3


break和continue的区别

  1. break终结当前所处层的的循环
  2. continue终结当前这一次循环
    ```swift
    for i in 1…10
    {
    if(i==3)
    {break
    }
    print(i)
    }
print(“continue的区别”)
for i in 1…10
{
if(i==3)
{
continue //跳过3
}
print(i)
}


## 字符串
```swift
var str = "Hello, playground"  //声明字符串变量
let str1 = "Hello"
var str2 : String = "HELLO 2"
str2.append(" swift")  //累加

str += "!"  //给可变字符串添加
print(str)
print(str.count)  //获取字符串的长度
print(str.contains(str1))
print(str.starts(with: str1))
//print(st)
print(str2)


可空类型 Optional

可空类型Optional是Swift的独特特性,用来指定某个实例没有值。一个可空类型的实例,要么已经可用,要么没有值就称为nil

声明可空类型

通过这种方式,编译器知道实例是否可能为nil,这种显示的声明让代码更具表达力,也更安全。


var erroInfo :String? //声明可空类型 ?
print(erroInfo)  //输出nil
//erroInfo += "test"
erroInfo = "test"
print(str)   //输出 ”Swift“
print(erroInfo)  //输出 Optional("test")


增加条件语句


if erroInfo != nil
{
    let theErro = erroInfo!  //感叹号的作用是强制展开可空类型
    print(theErro)  //输出"test"
}


可空类型的示例绑定


if let theErrors = erroInfo
{
    //当erroInfo不为nil 则给theErrors赋值,并执行当前代码块
    print(theErrors)
}


展开多个可空实例


var code : Int?
code = 401
if let theError = erroInfo, let theCode = code
{
    print("展开多个可空实例")
    print(theCode)
    print(theError)
}else
{
    print("不满足")
}


展开多个可空实例,和额外检查


if let theError = erroInfo, let theCode = code, code == 402
{
    print("展开多个可空实例")
    print(theCode)
    print(theError)
}


隐式展开可空实例

  1. 隐式展开可空实例的类型用 !声明,相比普通可空类型它不需要展开
  2. 表示要比普通可空类型更有信心
  3. 但存在着危险性:如果可空实例没有值访问其值会导致运行时错误var erroCodeInfo:String! erroCodeInfo = "no data" print("erroCodeInfo info is (erroCodeInfo)")

可空链式调用

  1. 可空链式调用运算符 ?.
  2. 与可空绑定类似,可空链式调用提供了一种对可空实例进行查询以判断其是否包含值的机制。
    可空链式调用允许把多个查询串联为一个可空实例的值,如果查询链中任意可空实例是nil,则返回nilvar erroInfo = nil //当 erroInfow不为空,则转为大写,为空则返回nil var erroInfoUp = erroInfo?.uppercased() // print(erroInfoUp) //原地修改可空实例 var

nil合并运算符

  1. nil合并运算符 ??
  2. 从可空实例中获取值,或者使用默认值//要么获取值,要么默认值 let

数组 Array

数组是有序的


//数组的两种声明方式
var data:Array<String> //声明一个字符串数组
var datas2:[String] //声明一个字符串数组

var arrs2:[String] = ["xx","yy"]  //初始化数组
var arrs = ["a1"]  //数组声明的类型推断
print(arrs)
arrs.append("appenData")
print(arrs)
arrs[0] += "ap"
arrs[1] = "d2"  //替换指定下标的元素
print(arrs)
print("数组长度count = (arrs.count)")
arrs += arrs2 //两个数组相加
print(arrs)
print("------指定位置插入一个元素 'EN'-------")
arrs.insert("EN", at: 2)
print(arrs)
print(arrs[0...2])  //打印下标前三的元素

var newArr = ["xx","yy"]
//判断两个数组是否相等,数组是有序的,需元素顺序和内容完全一致才算相等
print(newArr == arrs2) 

print("常量数组 一旦创建不可修改")
let finalArrays = ["a","b"]
print(finalArrays)
//finalArrays[0] = "66"


集合 set

集合是无序、元素唯一


//初始化一个集合
var hashSet = Set<String>() //声明一个String类型的集合
var set1:Set = ["a","b","c"]
print(set1)

//集合增加元素
hashSet.insert("a")
hashSet.insert("b")
print(hashSet)
循环遍历插入
for i in 4...8
{
    hashSet.insert("number (i)")
}
//print(hashSet)

//包含指定元素
hashSet.contains("a")
print(hashSet.contains("a"))
//print(hashSet.contains(set1))

//并集 union
let newSet = hashSet.union(set1)
print(newSet)

//交集 intersection,返回两个集合的共同部分的集合
let intersectionSet = hashSet.intersection(set1)
print("intersection (intersectionSet)")

//不相交,判断两个集合是否不相交, 相交则返回false
let isDisjointSet = hashSet.isDisjoint(with: set1)
print(isDisjointSet)


字典 Dictionary

  1. Dictionary 使用键值对(key-value pair)组织其内容
  2. Dictionary的键值必需是唯一的

Dictionary字典的四种初始化方式


var dict1 : Dictionary<String , Integer> = [:]
var dict2 :[String:Integer] = [:]
var dict3 = Dictionary<String,Integer>()
var dict4 = [String : Integer]()


字典初始化的类型推断


var dict :Dictionary<String,Int> = ["Tom":12 , "Jerry":18]
var dict2 = ["Tom":12 , "Jerry":18]


字典value的修改


var dict :Dictionary<String,Int> = ["Tom":12 , "Jerry":18]
//var dict2 = ["Tom":12 , "Jerry":18] //字典初始化的类型推断
print(dict)

访问和修改字典内容 ,key类型默认应为可空的数据n类型
print(dict["Tom"])  //输出内容为 Optional(12)
print(dict["jj"])  //输出内容为 nil
dict["Tom"] = 66  //修改字典的值
print(dict["Tom"])
dict.updateValue(99, forKey: "Jerry") //使用updateValued方法修改字典中指定键的值


新建字典元素


//print("新建字典元素")
//如字典中key为“Jake”的元素不存在则新建,否则则修改;
//测试发现字典是无序的,插入的字典值不一定在字典的最末,也可能插入到中间
//dict["Jake"] = 25
//print(dict)
删除字典元素
//print("删除字典元素:removeValue(forkey: ..)")
//dict.removeValue(forKey: "Jake")
//print(dict)


循环遍历字典


//循环遍历字典
for (key,value) in dict{
    print("The name is (key), age is (value)")
}

//遍历字典键值
for key in dict.keys
{
    print("the dict key is (key)")
}

//只遍历字典的值
for value in dict.values
{
    print("the dict value is (value)")
}


声明常量字典,不可再进行编辑


let album = ["he":11 , "me":99 , "she":88]
print(album.count)


把字典转为数组 Array


var keys = Array(dict.keys)
print(keys)   //["Tom", "Jerry"]
var values = Array(dict.values)
print(values)  //[12, 18]


value为数组的字典


//创建一个字典用于存储程序开发需要语言,如 key为ios,value为 ["Objective-c","Swift"]
print("创建一个字典用于存储程序开发需要语言")
var codeDict = ["ios":["Objective-c","Swift"] , "android":["java","kotlin"]]
print(codeDict)