Swift初見(一)

??Swift是一種安全,快速互動的編程語言,將現(xiàn)代編程語言的精華和蘋果工程師文化的智慧,以及來自開源社區(qū)的多樣化共享結(jié)合了起來。對于初學(xué)者的表達力也很友好。是一門滿足工業(yè)標準,但又有腳本語言表達力可玩性。支持代碼預(yù)覽,可以讓程序員在不編譯和運行程序的前提下運行Swift代碼實時查看結(jié)果。
通過采用現(xiàn)代編程模式來避免大量常見編程錯誤:

  • 變量始終在使用前初始化
  • 檢查數(shù)組索引超出范圍的錯誤
  • 檢查整數(shù)是否溢出
  • 可選值確保明確處理nil
  • 內(nèi)存自動管理
  • 錯誤處理允許從意外故障控制恢復(fù)

簡單值

  • 使用let來聲明常量,使用var來聲明變量
var myNumber = 42
myNumber = 50
let myConstant = 42
  • 不同類型的值不能一起相互拼接
// 編譯器會自動推斷其類型
let label = "The width is "
let width = 94
let aa = 4.95

// 錯誤
let widthLabel = label + width
let bb = width + aa

// 正確
let widthLabel = label + String(width)
let bb = width + Int(aa)
  • \()其他類型轉(zhuǎn)為字符串
let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "I have \(apples + oranges) pieces of fruit."
  • """包含多行字符串內(nèi)容,
 let apples = 3
 let oranges = 5
 let quotation = """
I said "I have \(apples) apples."
And then I said "I have \(apples + oranges) pieces of fruit."
"""
  • []創(chuàng)建空數(shù)組[:]創(chuàng)建空字典,并使用下標或者來訪問元素,
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"

var occupations = [
    "Malcolm": "Captain",
    "Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"

//空數(shù)組和空字典,字典是一個無序的集合
shoppingList = []
occupations = [:]
  • append添加元素
shoppingList.append("blue paint")
print(shoppingList)

控制流

  • 使用ifswitch來進行條件操作
// if
let score = 80
if score > 60 {
   print("及格")
} else {
   print("不及格")
}
*************************************
// switch 匹配到case語句之后,程序會退出switch語句,不會繼續(xù)向下運行,所以不需要在每個子句結(jié)尾寫break
let vegetable = "red pepper"
switch vegetable {
case "celery":
    print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
    print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):
    print("Is it a spicy \(x)?")
default:
    print("Everything tastes good in soup.")
}
  • 使用for-inwhilerepeat-while來進行循環(huán)
// for-in
let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
    if score > 50 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
print(teamScore)

// 在for-in中可以使用"..<"來表示下標范圍(不包含上界,如果想包含的話使用"...")
var total = 0
for i in 0..<4 {
    total += i
}
print(total)
*************************************

// while
var n = 2
while n < 100 {
    n *= 2
}
print(n)
*************************************

// repeat-while
var m = 2
repeat {
    m *= 2
} while m < 100
print(m)

函數(shù)和閉包

  • 使用func來聲明一個函數(shù),使用名字和參數(shù)來調(diào)用函數(shù)。使用->來指定函數(shù)返回值的類型
func greet(person: String, day: String) -> String {
    return "Hello \(person), today is \(day)."
}
greet(person:"Bob", day: "Tuesday")
  • 使用元組來生成復(fù)合值,該元組的元素可以用名字數(shù)字來獲取
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
    var min = scores[0]
    var max = scores[0]
    var sum = 0

    for score in scores {
        if score > max {
            max = score
        } else if score < min {
            min = score
        }
        sum += score
    }

    return (min, max, sum)
}
let statistics = calculateStatistics(scores:[5, 3, 100, 3, 9])

//獲取元組的元素
print(statistics.sum)
print(statistics.2)
  • 函數(shù)可以嵌套,一般用來重構(gòu)一個太長或者太復(fù)雜的函數(shù)
func returnFifteen() -> Int {
    var y = 10
    func add() {
        y += 5
    }
    add()
    return y
}
returnFifteen()
  • 函數(shù)是第一等類型,這意味著函數(shù)可以作為另一個函數(shù)的返回值
func makeIncrementer() -> ((Int) -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

??看到這里是不是有點懵逼((Int) -> Int)這句呢?((Int) -> Int)表示一個閉包(或函數(shù)),接受一個Int參數(shù)并返回一個Int。其實你可以這么想,var increment = makeIncrementer()這個拿到了addOne這個函數(shù),然后addOne需要一個為Int類型的參數(shù),所以前面那個(Int)指的是addOne的參數(shù)。

  • 函數(shù)也可以當作參數(shù)傳入另一個函數(shù)
func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}
func lessThanTen(number: Int) -> Bool {
    return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(list: numbers, condition: lessThanTen)

對象和類

使用class類名來創(chuàng)建一個類。類中的屬性的聲明和我們之前看到常量、變量的聲明一樣,唯一區(qū)別是它們的上下文是。

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}
  • 訪問
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()
  • init構(gòu)造器
class NamedShape {
    var numberOfSides: Int = 0
    var name: String

    init(name: String) {
        self.name = name
    }

    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

// 調(diào)用
let shape = NamedShape(name: "測試")
shape.numberOfSides = 11
print(shape.simpleDescription())

??這里我們用init來創(chuàng)建一個構(gòu)造器,這樣你創(chuàng)建實例的時候,像傳入函數(shù)參數(shù)一樣給類傳入構(gòu)造器的參數(shù)。

  • deinit析構(gòu)器
deinit {
     print("析構(gòu)器")
 }

??與init相對應(yīng),通常你不需要使用deinit,當你的實例化對象不在使用時,系統(tǒng)會自動幫你管理內(nèi)存,如果你需要在對象釋放之前進行一些清理工作的話,那么就可以使用deinit創(chuàng)建一個析構(gòu)函數(shù)。

  • override,子類如果重寫父類的方法的話,需要用這個標記,不然會報錯
class Square: NamedShape {
    var sideLength: Double

    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }

    func area() ->  Double {
        return sideLength * sideLength
    }

    override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()
  • getset
var perimeter: Double {
        get {
            return 3.0 * sideLength
        }
        set {
            sideLength = newValue / 3.0
        }
    }

??我們這里是聲明屬性perimeter,然后perimetersetter中,新值的名字是newValue(??:xxx.perimeter=1010)

  • willSet、didSet這兩個叫做屬性觀察器,當你不需要計算屬性,但是仍然需要設(shè)置一個新值之前或者之后運行代碼的時候使用
class aaa {
    var bbb: Int = 0 {
        willSet(newA) {
            print ("new is \(newA)" )
        }   
        
        didSet {
            if bbb > oldValue {     // oldValue是系統(tǒng)層面定義的 對舊值的標簽名,不用提前聲明,可以直接用。
                print("increase \(bbb - oldValue)")
            } else {
                print("new bbb is small than oldValue")
            }
        }
    } 
}

枚舉和結(jié)構(gòu)體

  • 使用enum來創(chuàng)建一個枚舉,可以包含方法
enum Rank: Int {
        case ace = 1
        case two, three, four, five, six, seven, eight, nine, ten
        case jack, queen, king
        func simpleDescription() -> String {
            switch self {
            case .ace:
                return "ace"
            case .jack:
                return "jack"
            case .queen:
                return "queen"
            case .king:
                return "king"
            default:
                return String(self.rawValue)
            }
        }
    }

// 調(diào)用
let ace = Rank.ace
let aceRawValue = ace.rawValue

??默認情況下,Swift按照從0開始每次加1的方式為原始值進行賦值,這里我們給ace = 1進行改變,使其從1開始。使用rawValue屬性來訪問一個枚舉成員的原始值。

  • 使用struct來創(chuàng)建一個結(jié)構(gòu)體,結(jié)構(gòu)體和類有很多相同的方法,包括方法和構(gòu)造器,最大區(qū)別是:結(jié)構(gòu)體是傳值,類是傳引用
struct Card {
    var rank: Rank
    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of aaa"
    }
}

//調(diào)用
let threeOfSpades = Card(rank: .three)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

協(xié)議和擴展

  • 使用protocol來聲明一個協(xié)議
protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}
  • 類、枚舉和結(jié)構(gòu)體都可以遵循協(xié)議
// 類
class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 69105
    func adjust() {
        simpleDescription += "  Now 100% adjusted."
    }
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription

// 結(jié)構(gòu)體
struct SimpleStructure: ExampleProtocol {
    var simpleDescription: String = "A simple structure"
    mutating func adjust() {
        simpleDescription += " (adjusted)"
    }
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription

mutating關(guān)鍵字用來標記一個會修改結(jié)構(gòu)體的方法

  • 使用 extension 來為現(xiàn)有的類型添加功能,比如新的方法計算屬性
extension Int: ExampleProtocol {
    var simpleDescription: String {
        return "The number \(self)"
    }
    mutating func adjust() {
        self += 42
    }
}
print(7.simpleDescription)

未完待續(xù).....

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容