带你初识Swift4.0,踏入Swift的大门

背景

由于Swift4之前的版本也看过好几遍,不过好久没看有点忘记了,不过这次看也是非常得心应手。项目中也准备引入Swift,所以作者再次详细看了The Swift Programming Language (Swift 4.0.3)英文官方文档一遍,并且详细列举了本人认为大家比较常用并且应该掌握的所有知识点。这里不做深入探究,如果哪里不懂的话,可以自行深入研究。

所有知识点

  • 数组可以用“+”表示两个数组组合
  • 字符串截取等操作很简洁
let greeting = "Hello, world!"
let index = greeting.index(of: ",") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello"
  • Dictionary可以遍历,并且支持移除操作
airports["APL"] = nil
或
removeValue(forKey:)

遍历:

for (airportCode, airportName) in airports {
    print("\(airportCode): \(airportName)")
}
  • switch语法很强大,很灵活,支持任何类型,比如字符串、范围、管道等等。而且不用break语句
case "a", "A":
case 1..<5:
case (-2...2, -2...2)
case let (x, y) where x == y
  • guard关键词使用使语句更简单明了
  • available判断api版本更简洁

if #available(iOS 10, macOS 10.12, *) {
    // Use iOS 10 APIs on iOS, and use macOS 10.12 APIs on macOS
} else {
    // Fall back to earlier iOS and macOS APIs
}
  • 函数可以返回多个值
func minMax(array: [Int]) -> (min: Int, max: Int) {
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}
  • 函数参数可以设置默认值
func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
    // If you omit the second argument when calling this function, then
    // the value of parameterWithDefault is 12 inside the function body.
}
someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6) // parameterWithDefault is 6
someFunction(parameterWithoutDefault: 4) // parameterWithDefault is 12
  • 可变参数...
func arithmeticMean(_ numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
  • inout 可以修改外部变量。与c语言指针有点类似
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA

  • 函数可以与属性变量一样对待。可以传递、取值等
  • 闭包(Closures)与Block类似
{ (parameters) -> return type in
    statements
}

*@escaping@autoclosure修饰闭包
@escaping使闭包在函数执行结束之前不会被执行。

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)//闭包没有执行,而是加到数组中了
}

@autoclosure简化了闭包的代用,不过代码会变的难懂,苹果建议尽量不使用

// customersInLine is ["Alex", "Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: () -> String) {
    print("Now serving \(customerProvider())!")
}
serve(customer: { customersInLine.remove(at: 0) } )
// Prints "Now serving Alex!"

使用之后:

// customersInLine is ["Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: @autoclosure () -> String) {
    print("Now serving \(customerProvider())!")
}
serve(customer: customersInLine.remove(at: 0))//大括号没有啦
// Prints "Now serving Ewa!"
  • 枚举功能很强大,很灵活,可以枚举的类型非常多,比如stringcharacterinteger
enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

var productBarcode = Barcode.upc(8, 85909, 51226, 3)

switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
    print("QR code: \(productCode).")
}
enum Planet: Int{}
enum ASCIIControlCharacter: Character {}
enum CompassPoint: String {}
  • indirect表示枚举中使用了自己
enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}
  • struct&&class
    struct传递是值传递;class是引用传递

In Swift, many basic data types such as String, Array, and Dictionary are implemented as structures. This means that data such as strings, arrays, and dictionaries are copied when they are assigned to a new constant or variable, or when they are passed to a function or method.

  • ===和!==用来比较对象
  • lazy懒加载,使用的时候再加载
  • 仅读属性。将get、set移除,直接返回,可以用来实例单例
struct Cuboid {
    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {
        return width * height * depth
    }
}
  • mutating用来修改struct和enum。因为二者是不能不能被自己的实例对象修改属性变量
struct Point {
    var x = 0.0, y = 0.0
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
// Prints "The point is now at (3.0, 4.0)"

**注意let不能修改**
let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveBy(x: 2.0, y: 3.0)
// this will report an error

enum TriStateSwitch {
    case off, low, high
    mutating func next() {
        switch self {
        case .off:
            self = .low
        case .low:
            self = .high
        case .high:
            self = .off
        }
    }
}
var ovenLight = TriStateSwitch.low
ovenLight.next()
// ovenLight is now equal to .high
ovenLight.next()
// ovenLight is now equal to .off
  • classstatic都可修饰类方法,class修饰的可以被子类重写
  • 脚标(Subscripts)。可以类、结构体、枚举定义脚标从而快速访问属性等。
subscript(index: Int) -> Int {
    get {
        // return an appropriate subscript value here
    }
    set(newValue) {
        // perform a suitable setting action here
    }
}
  • final可以防止被子类继承。
  • deinit 只有类有,当类销毁时会被回调。
  • ?是否为nil;??设置默认值
  • 异常处理
do {
    try expression
    statements
} catch pattern 1 {
    statements
} catch pattern 2 where condition {
    statements
}

try!明确知道不会抛出异常。

  • defer代码块执行后必须执行的代码
func processFile(filename: String) throws {
    if exists(filename) {
        let file = open(filename)
        defer {
            close(file)
        }
        while let line = try file.readline() {
            // Work with the file.
        }
        // close(file) is called here, at the end of the scope.
    }
}

  • is判断是否某个类型;as?as!转换至某个类型
  • Extensions与oc的category类似
extension SomeType: SomeProtocol, AnotherProtocol {
    // implementation of protocol requirements goes here
}
  • Protocols
protocol SomeProtocol {
    // protocol definition goes here
}

使用

struct SomeStructure: FirstProtocol, AnotherProtocol {
    // structure definition goes here
}
protocol SomeProtocol {
    var mustBeSettable: Int { get set }//有get和set方法
    var doesNotNeedToBeSettable: Int { get }//只有get方法,不能单独设置,只能在初始化的时候设置。
}
  • 检查是否遵循了某个协议

    • is遵循了返回true,否则返回false
    • as?遵循了正常转换,否则为nil
    • as!遵循了正常转换,否则抛出错误
  • 泛型(Generic);通常使用TUV等大写字母表示。

func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
    // function body goes here
}
  • weakunowned(与oc的unsafe_unretained类似)解决循环应用的问题
weak var tenant: Person?
  • 访问控制权限(open > public > interal > fileprivate > private)

    • private

      private 访问级别所修饰的属性或者方法只能在当前类里访问。
      (注意:Swift4 中,extension 里也可以访问 private 的属性。)

    • fileprivate

      fileprivate 访问级别所修饰的属性或者方法在当前的 Swift)

    • internal(默认访问级别,internal修饰符可写可不写)

      internal 访问级别所修饰的属性或方法在源代码所在的整个模块都可以访问。
      如果是框架或者库代码,则在整个框架内部都可以访问,框架由外部代码所引用时,则不可以访问。
      如果是 App 代码,也是在整个 App 代码,也是在整个 App 内部可以访问。

    • public

      可以被任何人访问。但其他 module 中不可以被 override 和继承,而在 module 内可以被 override 和继承。

    • open

      可以被任何人使用,包括 override 和继承。

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

推荐阅读更多精彩内容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,673评论 1 10
  • 基础部分(The Basics) 当推断浮点数的类型时,Swift 总是会选择Double而不是Float。 结合...
    gamper阅读 1,190评论 0 7
  • 136.泛型 泛型代码让你可以写出灵活,可重用的函数和类型,它们可以使用任何类型,受你定义的需求的约束。你可以写出...
    无沣阅读 1,395评论 0 4
  • 在人际交往中,自卑状态表现有两种。 一种自卑表现在不敢和他人交流,害怕自己表达的内容不是对方爱听的、想听的,同时,...
    山青云白心理阅读 1,269评论 0 1
  • 瓦房店,一座小城,我最美的灵魂过往都融入于此,无踪于此。它一次次的呼吸,一次次的变迁填塞着我的日子。城市越...
    W悟K空阅读 250评论 0 0