1.Swift特性

Swift 通过采用现代编程模式来避免大量常见编程错误:

  • 变量始终在使用前初始化。

  • 检查数组索引超出范围的错误。

  • 检查整数是否溢出。

  • 可选值确保明确处理 nil 值。

  • 内存被自动管理。

  • 错误处理允许从意外故障控制恢复。

Swift 5.3 写的项目可以依赖用 Swift 4.2 或 Swift 4 写的项目,反之亦然。这意味着,如果你将一个大的项目分解成多个框架(framework),你可以逐个地将框架从 Swift 4 代码迁移到 Swift 5.3。

Swift 中的 main 函数

/*
  在Swift中这句代码就是一个完整的程序
  全局作用域的代码会自动当做程序入口,所以Swift项目中不需要写main函数,也不需要;结尾
*/ 
print("Hello World")

变量类型的确定

  • 声明变量时直接初始化,那么系统会做自动类型推导
  • 如果声明变量时没有初始化,那么需要指定类型
  • 变量一旦声明,那么永远不会被隐式的转换为其他类型,需要显示转换
let carBrand = "BMW"
let carNum = 10086
let carInfo = carBrand + String(carNum)

var carOwner = """
    name = Jay;
    car = \(carInfo);
"""

数组和字典的初始化

// 数组
var arr = [Int]()
// 字典
var dic = [Int:Int]()

控制流

使用 ifswitch 来进行条件操作,使用 for-inwhilerepeat-while 来进行循环。

  • if

    • 条件必须是Bool表达式,不会隐形的于0做对比

    • 可以和 if - let 来处理(可选值类型)值丢失的情况

      if let content = opString {
          print(content)
      }else {
          print("可选值类型变量 opString 为空")
      }
      
  • switch

    • 匹配到case会退出,不需要加break
    let abc = "abc"
    let verify = "abc"
    // 支持任意类型(不仅仅整数), 各种比较(不仅仅测试相等)
    switch abc {
    case "ab":
        print("直接匹配")
    case "bc","bcd":
        print("匹配多个条件")
    case var verify where verify.hasPrefix("a"):
        print("verify转换为var")
        print("先验证verify是否包含指定前缀,再与abc匹配")
    default:
        print("不匹配")
    }
    
  • for-in

    //[String : [Any]]
    let info = [
        "name":["li","zhao","hua"],
        "age":[1,2,3],
    ]
    for dic in info {
        print ("key = \(dic.key)")
        let arr = dic.value
        // unit 是 Any类型
        for unit in arr {
            print(unit)
        }
    }
    
  • repeat-while 判断条件前会先执行一次代码块内的代码

函数和闭包

  • 函数返回值可以是元组生成的复合值
func doSome(num1:Int,num2:Int)->(sum:Int,max:Int){
    return (num1 + num2,max(num1, num2))
}
let value = doSome(num1: 1, num2: 2)
print("sum = \(value.sum),max = \(value.max)")
  • 函数是第一等类型,可以作为参数、返回值,函数间可以嵌套,内部嵌套的函数可以调用外部的参数
// 内嵌的函数作用域只在当前作用域
func run(name:String){
    func eat(){
        print("\(name) eat")
    }
    eat()
}

// 参数和返回值都为函数的函数
func executeParama(_:String){
    print("parama function")
}
func executeReturn(_:String)->String {
    return "return function";
}
func doNext(before: (String)->Void)->((String)->String) {
    before("")
    return executeReturn
}
let returnFunction = doNext(before: executeParama)
returnFunction("go")
  • 闭包
let nums = [1,2,3]
// map 创建了一个匿名闭包
let new = nums.map {
    // 通过 in 分离 参数-返回值类型 、函数体
    (num) -> Int in
    return num * 3;
}

let new2 = nums.map {
    //闭包的极简模式,$0 = 第一个参数,单行函数体,将作为返回值返回
    $0 * 3
}

func paramaBlock (num:Int,block:(Int)->Void){
    block(num)
}
// 闭包作为最后一个参数时,可以在函数调用()后面直接接大括号初始化这个block
paramaBlock(num: 3) { (num) in
    print("another parama num = \(num)")
}

类和对象

  • 存储属性(willSet/didSet),计算属性(setter/getter)
// 可以忽略父类
class Person {
    // 无默认值的存储属性需要在 init中 初始化
    var name:String
    // 可选值类型的属性不需要默认值
    var car:String?
    // 存储属性,可以通过 willSet 来监听值改变
    var money : Double {
        willSet (value) {
            // 默认值为 newValue,可以自定义这个常量名
            print("money = \(value)")
        }
    }
    // 计算属性,通过实现set / get 方法来使用
    var makeMoney : Double {
        set {
            money = newValue
        }
        get {
            return money
        }
    }
    init(name:String) {
        // 通过 self 区分参数和属性
        self.name = name
        money = 0
    }
}

class Student:Person {
    var studentNum:Int
    init(name: String,studentNum:Int) {
        /*
         1.初始化子类存储属性
         2.super.init
         3.给父类属性赋值
         */
        self.studentNum = studentNum
        super.init(name: name)
        money = 10
    }
}

可选值解包

var name:String?
// 通过?解包,如果可选值为nil,那么直接返回nil,后面不执行
name?.append("Jay")

枚举

  • 枚举值类型
  • 枚举成员设置关联值
// 枚举需要明确类型,如果是String类型,枚举成员的默认值就是该成员转字符串
enum Rank:Int{
    // 默认是从0开始,可以显示的指定起始值
    case one = 1
    case two,three,four,five,six,seven
    case king,ace,Unknown
    // 枚举可以包含方法
    func simpleDescription() -> String {
        switch self {
        case .one:
            return "one"
        default:
            return String(self.rawValue)
        }
    }
}
// 通过原始值创建一个 枚举实例
let rank:Rank = Rank.init(rawValue: 11) ?? Rank.Unknown
let str = rank.simpleDescription()
print("output = \(str)") // output = 10


enum Result {
    // 给枚举成员设置关联值
    case succese(Int,String)
    case fail(Int,String)
}

let result = Result.succese(200, "请求成功")
switch result{
case .succese(200, "请求中"):
    break
case .succese(200, "请求成功"):
    print("满足条件")
    break
default:
    break
}

结构体

  • 结构体和类的最大区别在于,结构体是值传值,类是地址传值

协议

// 枚举、结构体、类都可以遵守协议
protocol RunAble {
    // 此处只能进行声明
    var speed : Int {get}
   //mutating 对枚举和结构体这种值类型起作用,在方法内部可以修改 枚举、结构体对象的值
    mutating func run()
}

struct People:RunAble {
    var speed: Int = 10
    mutating func run() {
        speed = 0
    }
    func eat(){    
    }
}

// 明确对象的协议类型后,那么对象就只能调用协议内的属性和方法,即便实际执行对象有别的方法,也不能调用
let protocolValue: RunAble = people
print(protocolValue.run)
// print(protocolValue.eat)  // 去掉注释可以看到错误

延展

  • 使用 extension 来为现有的类型添加功能,比如新的方法和计算属性。你可以使用扩展让某个在别处声明的类型来遵守某个协议,这同样适用于从外部库或者框架引入的类型。
extension Int: ExampleProtocol {
    var simpleDescription: String {
        return "The number \(self)"
    }
    mutating func adjust() {
        self += 42
    }
}
print(7.simpleDescription)

错误处理

// 1.先定义一个继承于 Error的错误枚举
enum AppError : Error {
        case noKey
        case noName
    }
// 2.函数内部要使用 thorw抛出错误,那么要在参数后面加throws,根据调用函数的方式确定是否有返回值
func testError(code:Int) throws -> Int {
        if(code != 200){
            throw AppError.noKey
        }
        return 3
    }
// 3.1 直接解包调用  ?或者 !
let result = try? testError(code: 300)
// 3.2 通过do-catch捕获错误,不需要解包,如果throw,那么不会走do里面的代码
        do {
           let abc = try testError(code: 300)
           print(abc)
        } catch AppError.noKey {
            print("no key")
        } catch AppError.noName {
            print("no name")
        }catch {
            print("default")
        }

defer 代码块

  • 函数返回前最后执行
func testDefer (){
    defer {
        print("函数内的defer");
    }
    if(true){
        defer {
            print("if 中的 defer")
        }
        print("if 中的print")
    }
    if(true){
        return
    }
    print("函数结尾")
}

泛型

  • 函数 + 泛型 , 尖括号

    func repeatObj<T>(repeat item:T,count:Int)->[T]{
        var results:[T] = []
        for _ in 0 ..< count  {
            results.append(item)
        }
        return results
    }
    
    // 进阶:取交集
    func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Element]
    where T.Element: Equatable, T.Element == U.Element
    {
        var result:[T.Element] = []
        for lhsItem in lhs {
            for rhsItem in rhs {
                if lhsItem == rhsItem {
                    result.append(lhsItem)
                }
            }
        }
        return result
    }
    
    let result = anyCommonElements(["A", "B", "C"], ["C"])
    let result2 = anyCommonElements([1, 2, 3], [3])
    
  • 枚举 + 泛型

    enum OptionalValue<T> {
        case none
       // 枚举成员关联值,关联值类型是个泛型
        case some(T)
    }
    let p1 = OptionalValue.some(1)
    let p2 = OptionalValue.some("jay")
    switch p2 {
        case .some("luc"):
            print("luc")
        case .some("jay"):
            print("jay")
        default:
            print("default")
        break
    }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容