Swiftswift

Swift编程

2019-12-17  本文已影响0人  litongde
Swift语言基础.jpg

简介

Swift 语言学习路线及重难点

常量与变量

什么是常量和变量

常量和变量的使用注意

数据类型

类型推导

运算符

常见的运算符

元组

// 元组的常见写法
var one = ("李四", 30, 1.75)
var two = (name:"李四", age:30, height:1.75)
let (errorCode, errorInfo) = (404, "Not Found")

逻辑分支

// if 的使用
if a > 9 {
  print(a)
}

// guard 的使用
guard 条件表达式 else {
  // guard是Swift2.0新增的语法,跳转语句一般是return、break、continue、throw
}
语句组

switch 分支

循环

for 循环

// for in 循环
for i in 0..<10 {
  print(i)
}
// 特殊写法 如不需要用下标i
for _ in 0...10 {
  print("hello swift")
}

while 和 repeat while 循环

var a = 0
while a < 10 {
  a = a + 1
}

var b = 0
repeat {
  b = b + 1
} while b < 20

字符串

字符串常用操作

// 1、拼接 使用 + 或 append
let str = "abc" + "def"
// 2、遍历
for (index, value) in str.enumerated() {
  print("\(index) --- \(value)")
}
// 3、大写或小写
str.lowercased().uppercased()
// 4、含有字符串
str.contains("cd")
// 5、分割
let str1 = "aa&$$bb$$cc$$dd"
let desc = str1.components(separatedBy: "$$")
// 6、替换
let desc1 = str1.replacingOccurrences(of:"$$", with:"**")
// 7、子串
str.prefix(5) // 截取前5个字符
str.suffix(5) // 截取后5个字符
str.index(str.startIndex, offsetBy: -2)
let sub1 = str[0..<5] // 从位置0开始到5结束获取字符串

数组

// 定义
var array = ["zhangsan", "lisi", "wangwu"]

// 基本操作
array.count           // 获取长度
array.isEmpty         // 判空
array.append("l")     // 添加数据
array.insert("wo", at:0)  // 插入元素
array.dropFirst()     // 删除元素
array[0] = "fangqi"   // 修改元素
array.reverse()       // 倒序

// 遍历
for (index, name) in array.enumerated() {
  print(index)
  print(name)
}

字典

// Swift中任意类型用Any表示,如下定义字典
var dict: [String:Any] = ["name":"张三", "age":18]

// 基本操作
dict.count        // 获取长度
dict.isEmpty      // 判空
dict["height"] = 1.82  // 添加数据
dict.removeValue(forKey: "height")  // 删除字段
dict["name"] = "lisi" // 修改字典 或使用 dict.updateValue("lisi", forKey:"name")

// 遍历
for (key, value) in dict {
  print("\(key) --- \(value)")
}

可选型 (重点)

// 定义可选类型
let name: String? = nil
// 取出可选类型的值 ! 强制解包(显示解包)
print(name!) // 如果可选类型为nil,会报错

// 可选绑定(隐式解包)
if let str = name {
  print(str) // 此时输出就是str的值,而不是Optional
}
// 或使用guard取出可选类型的值
guard let str = name else {
  return 
}
print(str)

类型转换

类型转化符号 is 和 as

// 定义数组
let array: [Any] = [12, "zhangsan"]
// 取出数组中最后一个元素
let objcLast = array.last!
// is 判断元素是否是一个Int类型
if objcLast is Int {
  print("是Int类型")
}

// as? 将Any转成可选类型,通过判断可选类型是否有值,来决定是否转化成功了
let name = objcLast as? String
print(name)   // 结果:Optional("zhangsan")

// as! 将Any转成具体的类型,如果不是该类型,那么程序会崩溃
let name2 = objcLast as! String
print(name2)  // 结果:zhangsan

Any、AnyObject

函数

func 函数名(参数列表) -> 返回值类型 {
  return 返回值
}

函数的使用注意

函数类型

闭包

// 闭包表达式
{ (parameters) -> (return type) in 
  statements
}

闭包参数名称缩写

let array = getList(score: [65,75,85,95], op: { (num: Int) -> Bool in return num>80 })
// 简写一:省略 -> 与返回值类型
let array1 = getList(score: [65,75,85,95], op: { (num: Int) in return num>80 })
// 简写二:省略参数类型和括号
let array2 = getList(score: [65,75,85,95], op: { num in return num>80 })
// 简写三:省略 return 关键字
let array3 = getList(score: [65,75,85,95], op: { num in num>80 })
// 简写四:参数名称缩写,省略参数声明和 in,改为$0
let array4 = getList(score: [65,75,85,95], op: { $0>80 })

捕获

尾随闭包

func doSomething(info: String, clousre: (String) -> Void) {
  clousre(info)
}
// 使用尾随闭包进行函数调用
doSomething(info: "World") { s in 
  print(s)
}

逃逸闭包

自动闭包

Swift中闭包在官方系统库中的应用函数

  1. sort —— 排序
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
// 这种默认升序
array.sorted()
// 如果需要降序
array.sort { (str1, str2) -> Bool in 
  return str1 > str2
}
  1. forEach —— 遍历
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
// 遍历
array.forEach { (str) in 
  print(str)
}
  1. filter —— 筛选
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
// 筛选
let a = array.filter { (str) -> Bool in 
  str.starts(with: "A")
}
  1. map —— 变换
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
// 闭包返回一个变换后的元素,接着组成一个新数组
let a = array.map { (str) -> String in 
  "Hello " + str
}
  1. reduce —— 合归
var sum:[Int] = [11, 22, 33, 44]
var total = sum.reduce(0) { (result, num) -> Int in 
  return result + num
}
  1. allSatisfy —— 条件符合
// 判断数组的所有元素是否全部大于85
let scores = [86, 88, 95, 92]
// 检查序列中的所有元素是否满足条件,返回Bool
let passed = scores.allSatisfy { $0 > 85 }
  1. compactMap —— 转换
let arr: Array = [1, 2, 34, 5, 6, 7, 8, 12, 45, 6. 9]
// 返回操作的新数组(并不是筛选),数组,字典都可以使用
let compact = arr.compactMap({ $0%2 == 0})
  1. mapValues —— 转换value
let dic = ["first":1, "second":2, "three":3, "four":4]
// 字典中的函数,对字典的value执行操作,返回改变value后新的字典
let mapValues = dic.mapValues({ $0 + 2 })
  1. compactMapValues —— 上面两个的合并
let dic = ["first":1, "second":2, "three":3, "four":4, "five":"abc"]
// 将上述两个方法的功能合并在一起,返回一个对value操作后的新字典,并且自动过滤不符合条件的键值对
let newDic = dic.compactMapValues({Int($0)})

first(where:) —— 筛选第一个符合条件的
last(where:) —— 筛选最后一个符合条件

var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
let elementF = array.first(where: { $0.hasPrefix("A") })
let elementL = array.last(where: { $0.hasPrefix("A") })

removeAll(where:) —— 删除

// 高效根据条件删除,比filter内存效率高,指定不想要的东西
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
array.removeAll(where: { $0.hasPrefix("A") })

枚举

Swift中的枚举是一等类型,它可以像类和结构体一样增加 属性和方法

枚举定义

enum Sex {
  case male
  case female
}

枚举赋值

枚举类型推断

枚举原始值

枚举遍历

enum Method: CaseIterable {
  case Add, Sub, Mul, Div
}
for method in Method.allCases {
  print(method)
}

枚举的可选参数

// Swift5之后,可变参数的枚举定义时,...改成了数组
enum ABC {
  // case abc(argv: Int...) 
  case abc(argv: [Int])
}
func getABC() -> ABC {
  return .abc(argv: [0, 1, 2, 3])
}

结构体

字符串,数组和字典的赋值与拷贝行为

类与结构体对比

属性与方法

类的属性介绍有多种

总结

监听属性的改变

值类型在实例方法中修改属性和调用方法

类方法

class 和 static 总结

构造与析构函数

默认构造函数

自定义构造函数

Swift为类 类型定义了两种构造函数以确保所有存储属性接收一个初始值,指定构造函数和便捷构造函数

// 类的指定构造函数
init(parameters) {
  statements
}
// 便捷构造函数需用 convenience 修饰符放到 init 关键字前
convenience init(parameters) {
  statements
  self.init(parameters)
}

析构函数

协议 protocol

协议可被类、结构体、或枚举类型采纳以提供所需功能的具体实现即遵循协议

扩展 extension

面向协议编程
针对某个需要实现的功能,可以使用协议定义出接口,然后利用协议扩展提供默认的实现,需要这个功能,只需要声明遵守这个协议即可,遵守某个协议的对象调用协议声明的方法时,如果遵守者本身没有提供实现,协议扩展提供的默认实现会被调用

泛型

类型约束 和 关联类型

func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
}

protocol SomeProtocol {
  associatedtype Element: Equatable
  func method1(element: Element)
}

异常

// 1、定义异常
enum FileReadError: Error {
  case FileIsNull
  case FileNotFound
}

// 2、让方法抛出异常
func readFileContent(filePath: String) throws -> String {
  if filePath == "" {
    throw FileReadError.FileIsNull
  }
  if filePath != "/User/Desktop/123.plist" {
    throw FileReadError.FileNotFound
  }
  return "123"
}

// 处理异常
do {
  let result = try readFileContent(filePath: "abc")
} catch {
  print(error) // 有一个隐藏参数 error
}

// defer关键字

Result

// 使用Result处理异常如下
func readFileContent(filePath: String) -> Result<String, FileReadError> {
  if filePath == "" {
    return .failure(.FileIsNull)
  }
  if filePath != "/User/Desktop/123.plist" {
    return .failure(.FileNotFound)
  }
  return .success("123")
}

// 调用
let result = readFileContent(filePath: "")
switch result {
  case .failure(let error) 
    print(error)
  case .success(let content)
    print(content)
}

元类型、.self 与 Self

@objc关键字

出于安全的考虑,需将暴露给Objective-C使用的如类、属性和方法的声明前面加上@objc

  1. #selector 中调用的方法需要在方法前声明@objc
  2. 协议的方法可选时,协议和可选方法前要用@objc声明
  3. 用weak修饰的协议时 ,协议前面要用@objc声明
  4. 类上加@objcMembers,则其及子类、扩展里的属性和方法都会隐式的加上@objc,如果部分不想加,可以用@nonobjc修饰
  5. 扩展前加上@objc,那么里面的方法都会隐式加上@objc

where关键字

where关键字的含义和数据库中差不多,用于条件筛选,在Swift中哪些地方用到,如下总结

  1. Switch case 分支
  2. for 循环
  3. protocol 协议
  4. Generic 泛型
  5. do catch 异常处理

Key Path

// Swift 3 之前 
stu.value(forKey: "name")
stu.setValue("lisi", forKey: "name")
// Swift 3
stu.value(forKey: #keyPath(Student.sex))
stu.setValue("女", forKey: #keyPath(Student.sex))
// Swift 4
stu[keyPath: \Student.sex]
stu[keyPath: \Student.sex] = "女"

Codable协议

访问权限

注意

学习参考

学习网址

上一篇下一篇

猜你喜欢

热点阅读