zoukankan      html  css  js  c++  java
  • Swift简介

    1. swift初始来源

        没有了解过swift可以先参考Brec VictorInventing on Principle ,Swift编程环境的大部分概念都源自于Brec这个演讲。

    2. swift是啥

    Swift是苹果在WWDC 2014发布的新的编程语言,这里引用The Swift Programming Language的原文:

    Swift is a new programming language for iOS and OS X apps that builds on the best of C and Objective-C, without the constraints of C compatibility.

    Swift adopts safe programming patterns and adds modern features to make programming easier, more flexible and more fun.

    Swift’s clean slate, backed by the mature and much-loved Cocoa and Cocoa Touch frameworks, is an opportunity to imagine how software development works.

    Swift is the first industrial-quality systems programming language that is as expressive and enjoyable as a scripting language.

    简单的说:

    1. Swift用来写iOS和OS X程序。(估计也不会支持其它屌丝系统)
    2. Swift吸取了C和Objective-C的优点,且更加强大易用。
    3. Swift可以使用现有的Cocoa和Cocoa Touch框架。
    4. Swift兼具编译语言的高性能(Performance)和脚本语言的交互性(Interactive)。

    3.Swift语言概览

    基本概念

    注:这一节的代码源自The Swift Programming Language中的A Swift Tour

    Hello, world

    类似于脚本语言,下面的代码即是一个完整的Swift程序。

    1 println("Hello, world")

    变量与常量

    Swift使用var声明变量,let声明常量。

    1 var myVariable = 42
    2 myVariable = 50
    3 let myConstant = 42

    类型推导

    Swift支持类型推导(Type Inference),所以上面的代码不需指定类型,如果需要指定类型:

    1 let explicitDouble : Double = 70

    Swift不支持隐式类型转换(Implicitly casting),所以下面的代码需要显式类型转换(Explicitly casting):

    1 let label = "The width is "
    2 let width = 94
    3 let width = label + String(width)

    字符串格式化

    Swift使用(item)的形式进行字符串格式化:

    1 let apples = 3
    2 let oranges = 5
    3 let appleSummary = "I have (apples) apples."
    4 let appleSummary = "I have (apples + oranges) pieces of fruit."

    数组和字典

    Swift使用[]操作符声明数组(array)和字典(dictionary):

    1 var shoppingList = ["catfish", "water", "tulips", "blue paint"]
    2 shoppingList[1] = "bottle of water"
    3 
    4 var occupations = [
    5     "Malcolm": "Captain",
    6     "Kaylee": "Mechanic",
    7 ]
    8 occupations["Jayne"] = "Public Relations"

    一般使用初始化器(initializer)语法创建空数组和空字典:

    1 let emptyArray = String[]()
    2 let emptyDictionary = Dictionary<String, Float>()

    如果类型信息已知,则可以使用[]声明空数组,使用[:]声明空字典。

    控制流

    概览

    Swift的条件语句包含ifswitch,循环语句包含for-inforwhiledo-while,循环/判断条件不需要括号,但循环/判断体(body)必需括号:

    1 let individualScores = [75, 43, 103, 87, 12]
    2 var teamScore = 0
    3 for score in individualScores {
    4     if score > 50 {
    5         teamScore += 3
    6     } else {
    7         teamScore += 1
    8     }
    9 }

    可空类型

    结合iflet,可以方便的处理可空变量(nullable variable)。对于空值,需要在类型声明后添加?显式标明该类型可空。

    1 var optionalString: String? = "Hello"
    2 optionalString == nil
    3 
    4 var optionalName: String? = "John Appleseed"
    5 var gretting = "Hello!"
    6 if let name = optionalName {
    7     gretting = "Hello, (name)"
    8 }

    灵活的switch

    Swift中的switch支持各种各样的比较操作:

    let vegetable = "red pepper"
    switch vegetable {
    case "celery":
        let vegetableComment = "Add some raisins and make ants on a log."
    case "cucumber", "watercress":
        let vegetableComment = "That would make a good tea sandwich."
    case let x where x.hasSuffix("pepper"):
        let vegetableComment = "Is it a spicy (x)?"
    default:
        let vegetableComment = "Everything tastes good in soup."
    }

    其它循环

    for-in除了遍历数组也可以用来遍历字典:

     1 let interestingNumbers = [
     2     "Prime": [2, 3, 5, 7, 11, 13],
     3     "Fibonacci": [1, 1, 2, 3, 5, 8],
     4     "Square": [1, 4, 9, 16, 25],
     5 ]
     6 var largest = 0
     7 for (kind, numbers) in interestingNumbers {
     8     for number in numbers {
     9         if number > largest {
    10             largest = number
    11         }
    12     }
    13 }
    14 largest

    while循环和do-while循环:

     1 var n = 2
     2 while n < 100 {
     3     n = n * 2
     4 }
     5 n
     6 
     7 var m = 2
     8 do {
     9     m = m * 2
    10 } while m < 100
    11 m

    Swift支持传统的for循环,此外也可以通过结合..(生成一个区间)和for-in实现同样的逻辑。

     1 var firstForLoop = 0
     2 for i in 0..3 {
     3     firstForLoop += i
     4 }
     5 firstForLoop
     6 
     7 var secondForLoop = 0
     8 for var i = 0; i < 3; ++i {
     9     secondForLoop += 1
    10 }
    11 secondForLoop

    注意:Swift除了..还有.....生成前闭后开的区间,而...生成前闭后闭的区间。

    函数和闭包

    函数

    Swift使用func关键字声明函数:

    1 func greet(name: String, day: String) -> String {
    2     return "Hello (name), today is (day)."
    3 }
    4 greet("Bob", "Tuesday")

    通过元组(Tuple)返回多个值:

    1 func getGasPrices() -> (Double, Double, Double) {
    2     return (3.59, 3.69, 3.79)
    3 }
    4 getGasPrices()

    支持带有变长参数的函数:

    1 func sumOf(numbers: Int...) -> Int {
    2     var sum = 0
    3     for number in numbers {
    4         sum += number
    5     }
    6     return sum
    7 }
    8 sumOf()
    9 sumOf(42, 597, 12)

    函数也可以嵌套函数:

    1 func returnFifteen() -> Int {
    2     var y = 10
    3     func add() {
    4         y += 5
    5     }
    6     add()
    7     return y
    8 }
    9 returnFifteen()

    作为头等对象,函数既可以作为返回值,也可以作为参数传递:

    1 func makeIncrementer() -> (Int -> Int) {
    2     func addOne(number: Int) -> Int {
    3         return 1 + number
    4     }
    5     return addOne
    6 }
    7 var increment = makeIncrementer()
    8 increment(7)
     1 func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {
     2     for item in list {
     3         if condition(item) {
     4             return true
     5         }
     6     }
     7     return false
     8 }
     9 func lessThanTen(number: Int) -> Bool {
    10     return number < 10
    11 }
    12 var numbers = [20, 19, 7, 12]
    13 hasAnyMatches(numbers, lessThanTen)

    闭包

    本质来说,函数是特殊的闭包,Swift中可以利用{}声明匿名闭包:

    1 numbers.map({
    2     (number: Int) -> Int in
    3     let result = 3 * number
    4     return result
    5     })

    当闭包的类型已知时,可以使用下面的简化写法:

    1 numbers.map({ number in 3 * number })

    此外还可以通过参数的位置来使用参数,当函数最后一个参数是闭包时,可以使用下面的语法:

    1 sort([1, 5, 3, 12, 2]) { $0 > $1 }

    类和对象

    创建和使用类

    Swift使用class创建一个类,类可以包含字段和方法:

    1 class Shape {
    2     var numberOfSides = 0
    3     func simpleDescription() -> String {
    4         return "A shape with (numberOfSides) sides."
    5     }
    6 }

    创建Shape类的实例,并调用其字段和方法。

    1 var shape = Shape()
    2 shape.numberOfSides = 7
    3 var shapeDescription = shape.simpleDescription()

    通过init构建对象,既可以使用self显式引用成员字段(name),也可以隐式引用(numberOfSides)。

     1 class NamedShape {
     2     var numberOfSides: Int = 0
     3     var name: String
     4 
     5     init(name: String) {
     6         self.name = name
     7     }
     8 
     9     func simpleDescription() -> String {
    10         return "A shape with (numberOfSides) sides."
    11     }
    12 }

    使用deinit进行清理工作。

    继承和多态

    Swift支持继承和多态(override父类方法):

     1 class Square: NamedShape {
     2     var sideLength: Double
     3 
     4     init(sideLength: Double, name: String) {
     5         self.sideLength = sideLength
     6         super.init(name: name)
     7         numberOfSides = 4
     8     }
     9 
    10     func area() -> Double {
    11         return sideLength * sideLength
    12     }
    13 
    14     override func simpleDescription() -> String {
    15         return "A square with sides of length (sideLength)."
    16     }
    17 }
    18 let test = Square(sideLength: 5.2, name: "my test square")
    19 test.area()
    20 test.simpleDescription()

    注意:如果这里的simpleDescription方法没有被标识为override,则会引发编译错误。

    属性

    为了简化代码,Swift引入了属性(property),见下面的perimeter字段:

     1 class EquilateralTriangle: NamedShape {
     2     var sideLength: Double = 0.0
     3 
     4     init(sideLength: Double, name: String) {
     5         self.sideLength = sideLength
     6         super.init(name: name)
     7         numberOfSides = 3
     8     }
     9 
    10     var perimeter: Double {
    11     get {
    12         return 3.0 * sideLength
    13     }
    14     set {
    15         sideLength = newValue / 3.0
    16     }
    17     }
    18 
    19     override func simpleDescription() -> String {
    20         return "An equilateral triagle with sides of length (sideLength)."
    21     }
    22 }
    23 var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
    24 triangle.perimeter
    25 triangle.perimeter = 9.9
    26 triangle.sideLength

    注意:赋值器(setter)中,接收的值被自动命名为newValue

    willSet和didSet

    EquilateralTriangle的构造器进行了如下操作:

    1. 为子类型的属性赋值。
    2. 调用父类型的构造器。
    3. 修改父类型的属性。

    如果不需要计算属性的值,但需要在赋值前后进行一些操作的话,使用willSetdidSet

     1 class TriangleAndSquare {
     2     var triangle: EquilateralTriangle {
     3     willSet {
     4         square.sideLength = newValue.sideLength
     5     }
     6     }
     7     var square: Square {
     8     willSet {
     9         triangle.sideLength = newValue.sideLength
    10     }
    11     }
    12     init(size: Double, name: String) {
    13         square = Square(sideLength: size, name: name)
    14         triangle = EquilateralTriangle(sideLength: size, name: name)
    15     }
    16 }
    17 var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
    18 triangleAndSquare.square.sideLength
    19 triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
    20 triangleAndSquare.triangle.sideLength

    从而保证trianglesquare拥有相等的sideLength

    调用方法

    Swift中,函数的参数名称只能在函数内部使用,但方法的参数名称除了在内部使用外还可以在外部使用(第一个参数除外),例如:

    1 class Counter {
    2     var count: Int = 0
    3     func incrementBy(amount: Int, numberOfTimes times: Int) {
    4         count += amount * times
    5     }
    6 }
    7 var counter = Counter()
    8 counter.incrementBy(2, numberOfTimes: 7)

    注意Swift支持为方法参数取别名:在上面的代码里,numberOfTimes面向外部,times面向内部。

    ?的另一种用途

    使用可空值时,?可以出现在方法、属性或下标前面。如果?前的值为nil,那么?后面的表达式会被忽略,而原表达式直接返回nil,例如:

    1 let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional 
    2 square")
    3 let sideLength = optionalSquare?.sideLength

    optionalSquarenil时,sideLength属性调用会被忽略。

    枚举和结构

    枚举

    使用enum创建枚举——注意Swift的枚举可以关联方法:

     1 enum Rank: Int {
     2     case Ace = 1
     3     case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
     4     case Jack, Queen, King
     5         func simpleDescription() -> String {
     6         switch self {
     7             case .Ace:
     8                 return "ace"
     9             case .Jack:
    10                 return "jack"
    11             case .Queen:
    12                 return "queen"
    13             case .King:
    14                 return "king"
    15             default:
    16                 return String(self.toRaw())
    17         }
    18     }
    19 }
    20 let ace = Rank.Ace
    21 let aceRawValue = ace.toRaw()

    使用toRawfromRaw在原始(raw)数值和枚举值之间进行转换:

    1 if let convertedRank = Rank.fromRaw(3) {
    2     let threeDescription = convertedRank.simpleDescription()
    3 }

    注意枚举中的成员值(member value)是实际的值(actual value),和原始值(raw value)没有必然关联。

    一些情况下枚举不存在有意义的原始值,这时可以直接忽略原始值:

     1 enum Suit {
     2     case Spades, Hearts, Diamonds, Clubs
     3         func simpleDescription() -> String {
     4         switch self {
     5             case .Spades:
     6                 return "spades"
     7             case .Hearts:
     8                 return "hearts"
     9             case .Diamonds:
    10                 return "diamonds"
    11             case .Clubs:
    12                 return "clubs"
    13         }
    14     }
    15 }
    16 let hearts = Suit.Hearts
    17 let heartsDescription = hearts.simpleDescription()

    除了可以关联方法,枚举还支持在其成员上关联值,同一枚举的不同成员可以有不同的关联的值:

     1 enum ServerResponse {
     2     case Result(String, String)
     3     case Error(String)
     4 }
     5 
     6 let success = ServerResponse.Result("6:00 am", "8:09 pm")
     7 let failure = ServerResponse.Error("Out of cheese.")
     8 
     9 switch success {
    10     case let .Result(sunrise, sunset):
    11         let serverResponse = "Sunrise is at (sunrise) and sunset is at (sunset)."
    12     case let .Error(error):
    13         let serverResponse = "Failure... (error)"
    14 }

    结构

    Swift使用struct关键字创建结构。结构支持构造器和方法这些类的特性。结构和类的最大区别在于:结构的实例按值传递(passed by value),而类的实例按引用传递(passed by reference)。

    1 struct Card {
    2     var rank: Rank
    3     var suit: Suit
    4     func simpleDescription() -> String {
    5         return "The (rank.simpleDescription()) of (suit.simpleDescription())"
    6     }
    7 }
    8 let threeOfSpades = Card(rank: .Three, suit: .Spades)
    9 let threeOfSpadesDescription = threeOfSpades.simpleDescription()

    协议(protocol)和扩展(extension)

    协议

    Swift使用protocol定义协议:

    1 protocol ExampleProtocol {
    2     var simpleDescription: String { get }
    3     mutating func adjust()
    4 }

    类型、枚举和结构都可以实现(adopt)协议:

     1 class SimpleClass: ExampleProtocol {
     2     var simpleDescription: String = "A very simple class."
     3     var anotherProperty: Int = 69105
     4     func adjust() {
     5         simpleDescription += " Now 100% adjusted."
     6     }
     7 }
     8 var a = SimpleClass()
     9 a.adjust()
    10 let aDescription = a.simpleDescription
    11 
    12 struct SimpleStructure: ExampleProtocol {
    13     var simpleDescription: String = "A simple structure"
    14     mutating func adjust() {
    15         simpleDescription += " (adjusted)"
    16     }
    17 }
    18 var b = SimpleStructure()
    19 b.adjust()
    20 let bDescription = b.simpleDescription

    扩展

    扩展用于在已有的类型上增加新的功能(比如新的方法或属性),Swift使用extension声明扩展:

    1 extension Int: ExampleProtocol {
    2     var simpleDescription: String {
    3         return "The number (self)"
    4     }
    5     mutating func adjust() {
    6         self += 42
    7     }
    8 }
    9 7.simpleDescription

    泛型(generics)

    Swift使用<>来声明泛型函数或泛型类型:

    1 func repeat<ItemType>(item: ItemType, times: Int) -> ItemType[] {
    2     var result = ItemType[]()
    3     for i in 0..times {
    4         result += item
    5     }
    6     return result
    7 }
    8 repeat("knock", 4)

    Swift也支持在类、枚举和结构中使用泛型:

    1 // Reimplement the Swift standard library's optional type
    2 enum OptionalValue<T> {
    3     case None
    4     case Some(T)
    5 }
    6 var possibleInteger: OptionalValue<Int> = .None
    7 possibleInteger = .Some(100)

    有时需要对泛型做一些需求(requirements),比如需求某个泛型类型实现某个接口或继承自某个特定类型、两个泛型类型属于同一个类型等等,Swift通过where描述这些需求:

     
     1 func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool {
     2     for lhsItem in lhs {
     3         for rhsItem in rhs {
     4             if lhsItem == rhsItem {
     5                 return true
     6             }
     7         }
     8     }
     9     return false
    10 }
    11 anyCommonElements([1, 2, 3], [3])


    Swift语言概览就到这里,有兴趣的朋友请进一步阅读The Swift Programming Language。本文摘自http://zh.lucida.me/blog/an-introduction-to-swift/的部分内容。

  • 相关阅读:
    2021 Duilib最新入门教程(二)Duilib编译动态库
    2021 Duilib最新入门教程(一)Duilib简介
    webgl图库选型
    CUDA编程学习记录
    C++时间戳获取
    FFMPEG编译问题记录
    程序员的35岁
    Linux发行版及其目标用户
    服务器关机或重启
    Linux下找出吃内存的方法总结
  • 原文地址:https://www.cnblogs.com/xusd-null/p/3765489.html
Copyright © 2011-2022 走看看