Swift 基礎(chǔ)入門教程

此文章屬于Swift 基礎(chǔ)教程处窥,主要是全面的了解一下Swift的各種語法和函數(shù)破婆。
主要參考Swift文檔中的快速預(yù)覽模塊匈挖,期間搜索了最新的資料整理兄猩,加入了一些關(guān)鍵字的討論和確認。希望對你的學(xué)習(xí)有幫助半开。
如果有你的觀點和想法想和我討論隔披,歡迎留言。
github 地址

建議整體復(fù)制到你的playGround 運行

import UIKit

// 新語言的第一節(jié)  hello world
let helloWorld = "hello world!"
print(helloWorld)

//使用let 做常量 var 做變量 編譯器可以判斷值的類型 也可指定其類型 但是不會隱式的轉(zhuǎn)換成其他類型
let myNumber = 43
var mynumber01 = 45
mynumber01 = 46
let myNumber3: Double = 90
let label = "The width is "
let width = 99
let widthString = label + String(width)
let widthString01 = "The width is \(width)"
let widthString02 = "The width is \(mynumber01 + width) km"

//數(shù)值型字面量也可以增加額外的格式使代碼更加易讀寂拆。整數(shù)和浮點數(shù)都可以添加額外的零或者添加下劃線來增加代碼的可讀性奢米。下面的這些格式都不會影響字面量的值。
let paddedDouble: Float = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1

//""" 用于多行字符串 以下列出了兩種換行方式 需要注意的是:使用"""換行方式  不能和內(nèi)容在同一行  否則會報錯
let lineString = """
你好
我現(xiàn)在
不方便
去你那
請多包涵
"""
let lineString1 = "你好\n我現(xiàn)在\n不方便\n去你那"

//創(chuàng)建數(shù)組和字典 根據(jù)規(guī)范 最好漓库,后留出一個空格  :后留出一個空格
//在字典中如果類型不一致 或者無法判斷出類型恃慧,需要對其進行注釋,例如 : [String: Any]

/*
知識點:Any渺蒿、AnyHashable痢士、AnyObject、AnyClass的區(qū)別
Any是一個空協(xié)議集合的別名茂装,它表示沒有實現(xiàn)任何協(xié)議怠蹂,因此它可以是任何類型,包括類實例與結(jié)構(gòu)體實例少态,以及函數(shù)類型和可選類型城侧。
AnyHashable遵守Hashable協(xié)議的Any類型,是Any的子集合彼妻,主要用于Dictionary和Set中嫌佑。(Dictionary 要求它的Key類型需要遵守 Hashable協(xié)議)
AnyObject是一個成員為空的協(xié)議,任何對象都實現(xiàn)了這個協(xié)議侨歉。它是Any的子集合屋摇,Any中的類實例。
AnyClass是AnyObject.Type的別名而已幽邓。
可參考:https://blog.csdn.net/feosun/article/details/78002558
*/
var newArray = ["one", "two", "three", "four"]

//根據(jù)下標(biāo) 修改元素
newArray[1] = "nihao"

//添加元素
newArray.append("nibuhao")

var newDic: [AnyHashable: Any] = [
    "name": "xiaoming",
    "age": 88,
    88: 89,
]
newDic[88] = 999

//創(chuàng)建空數(shù)組或者字典,如果可以推斷用戶信息炮温,則可設(shè)置為空數(shù)組或者空字典
var emptyArray = [String]() //標(biāo)明元素類型
let emptyArray1 = [] as [String]
emptyArray = []

var emptyDic = [String: Any]()
let emptyDic1 = [:] as [String: Any]
emptyDic = [:]

let acores = [78,89,99,23,34,54,65]
var teamScore = 0
for score in acores {
    if score > 50 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
print(teamScore)

//在值的類型后加? 表示類型可選
var optionString: String? = "optionstring"
print(optionString == nil)

var optionName: String? = "fengfeng"
var greeting: String = "hello!"
if let n = optionName {
    greeting = "hello \(n)"
} else {
    print("name 是空的")
}

//處理可選值的另一種方法是使用牵舵?柒啤? 提供默認值
let chaoName1: String? = nil
let chaoName: String = "lichao"
let chao = "hello \(chaoName1 ?? chaoName)"

//switch 支持任意類型的數(shù)據(jù)的操作,不限于整數(shù)和相等的情況. 下面例子中的where關(guān)鍵字指定額外的要求畸颅,并且只能在使用switch的語句担巩,所有這些vagateble是泛型的,免去Swift中的類型轉(zhuǎn)換没炒。
//關(guān)于泛型可以參考(http://www.reibang.com/p/6624f5365745)比較重要

let vagateble = "daxiang"
switch vagateble {
case "dayali":
    print("shuiguoshi _ dayali")
case "pingguo":
    print("shuiguoshi _ pingguo")
case "juzi":
    print("shuiguoshi _ juzi")
case let x where x.hasPrefix("daxiang") :
    print("shuiguoshi _ daxiangjiao+++++++ \(x)")
default:
    print("shadoubushi")
}

//字典的迭代 iterate (不同類型的數(shù)字是不能比較大小的兵睛,比如Double 和 Int ,需要有一個轉(zhuǎn)換為相同類型才可以比較,這也是swift 安全性的體現(xiàn)之一)
let iterateDic = [
    "one": [2,3,4,67,78.8766,432],
    "two": [2,3,4,67,78.8766,432],
    "three": [2,3,4,67,78.8766,432],
    "four": [2,3,4,67,78.8766,432],
    "five": [2,3,4,67,78.8766,432],
]

var lagest: Double = 0
for (_, values) in iterateDic {
    for value in values {
        if value > lagest {
            lagest = value
        }
    }
}
print(lagest)

//while  repeat...while
var whileNumber = 2
while whileNumber < 200 {
    whileNumber += 33
}
print(whileNumber)


var repeatNumber = 3
repeat {
 repeatNumber += 20
} while repeatNumber < 300
print(repeatNumber)


//..< 不包括上限的值  ... 包括上限的值
var total = 0
for i in 1..<3 {
    total += i
}
print(total)

//函數(shù)和閉包
func greet(person: String, day: String) -> String {
    return "hello \(person) ,today is \(day)"
}
greet(person: "liuchao", day: "2018.9.27")

//在參數(shù)名前寫入自定義的參數(shù)標(biāo)簽(本例的at) 或者加 _ 可省略參數(shù)標(biāo)簽
func greet2(_ person: String, at day: String) -> String {
    return "hello \(person) ,today is \(day)"
}
greet2("liuchao", at: "2018.9.27")


// 同objectiveC相比祖很,swift多了一種結(jié)構(gòu)類型笛丙,就是元組(之后會講)
// 函數(shù)可使用元組 傳
入復(fù)合參數(shù)
func jisuanscores(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 result = jisuanscores(scores: [3,45,66,77,23,35,546,243,37])
print(result.min, result.max, result.sum)

//函數(shù)還可以嵌套
func returnFifteen() -> Int {
    var a = 10

    func add() {
        a += 5
    }

    add() //內(nèi)部函數(shù)的調(diào)用需要在函數(shù)聲明之后

    return a
}
returnFifteen()

//牛逼的是 函數(shù)還可以返回另一個函數(shù)作為返回值
func fanHuiHanShu() -> ((Int) -> Int) {

    func addNumber(number: Int) -> Int {
        return number + 23
    }
    return addNumber
}
let addNumber = fanHuiHanShu()
addNumber(33)

//既然函數(shù)可以作為返回值  那么函數(shù)同樣可以作為參數(shù)之一
func jianCeShiFouYouShiYiXia(list: [Int], condition: (Int) -> Bool) -> Bool {

    for number in list {

        if condition(number) {
            return true
        }
    }
    return false
}
let list = [2,3,4,5,6,7,23,43]
func lessThanTen(number: Int) -> Bool {
    return number < 10
}
jianCeShiFouYouShiYiXia(list: list, condition: lessThanTen)

//閉包closures 閉包是無名的,因為他們能夠從上下文中捕獲變量假颇、常量胚鸯,從而應(yīng)用在自身的作用區(qū)域。
let number0 = list.map({ (number: Int) -> Int in
    let result = 3 * number
    return result
})

print(number0)
print(list)

//還可以這樣寫笨鸡, 當(dāng)已知閉包的類型(例如委托的回調(diào))時姜钳,可以省略其參數(shù)的類型,返回類型或兩者形耗。 單個語句閉包隱式返回其唯一語句的值哥桥。
let number1 = list.map( { number in
    3 * number
})
print(number0)
print(list)

//您可以按編號而不是按名稱來引用參數(shù) - 這種方法在非常短的閉包中特別有用。
//作為函數(shù)的最后一個參數(shù)傳遞的閉包可以在括號后面立即出現(xiàn)激涤。
//當(dāng)閉包是函數(shù)的唯一參數(shù)時拟糕,可以完全省略括號。
let sortedNumbers = list.sorted { $0 > $1 }
print(sortedNumbers)

//閉包的聲明
var biBao: () -> String = {
    return "nihao"
}
//調(diào)用
biBao()

//無返回值的閉包
var biBao2: () -> () = {
    print("wobuhao")
}
biBao2()

//帶參數(shù)的閉包
var canShuBiBao: (String, Int) -> String = {
    (name: String, age: Int) -> String in

    let nameString = "我叫 \(name), 今年\(age)歲了倦踢!"
    return nameString
}
print(canShuBiBao("liuchao",89))

//帶參數(shù)的閉包簡化 根據(jù)參數(shù)自動推斷參數(shù)類型
canShuBiBao = {
    (name,age) in

    let nameString = "我叫 \(name), 今年\(age)歲了送滞!"
    return nameString
}
print(canShuBiBao("liuchao001",89))

//第二次閉包簡化 如果函數(shù)體只包含一句return 可省略return
canShuBiBao = {
    (name,age) in
    "我叫 \(name), 今年\(age)歲了!"
}
print(canShuBiBao("liuchao00333",89))

//第三次簡化 被捕獲的參數(shù)列表中 可通過 $ 獲取  可自行判斷出參數(shù)類型  所以可以省略 (name,age) in
canShuBiBao = {
    "我叫 \($0), 今年\($1)歲了辱挥!"
}
print(canShuBiBao("liuchao0033333333",89))

//對象和類 (: NSObject 可省略 )
class Person: NSObject {
    var name: String = "liuchao"
    let age: Int = 28

    var newName: String? {

//        set {
//        print(newValue)
//        }

        willSet {

            print(newValue ?? "")
        }

        didSet {

            print(oldValue ?? "")
        }

//        get {
//        return "new liuchao name"
//        }
    }


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

        super.init()
    }

    func nameAgeString() -> String {

        return "我叫 \(name), 今年\(age)歲了犁嗅!"
    }

    deinit {
        print("對象銷毀")
    }
}

let person = Person.init(name: "liuchao00999999")
person.name
person.age
person.newName = "newvalue liuhao------------"
person.newName
let nageAgeString = person.nameAgeString()

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

//使用該rawValue屬性可以訪問枚舉的原始值
enum LiuChao: Int {
    case abc = 1
    case two, three, four, five, six, seven
    case liuchao1, liuchao2, liuchao3

    func jianDanGuoLv() -> String {
        switch self {
        case .abc:
            return "001"
        case .two:
            return "002"
        case .three:
            return "003"
        case .liuchao1:
            return "004"
        case .liuchao2:
            return "005"
        case .six:
            return "006"
        case .four:
            return "007"
        default:
            return "------"
        }
    }
}
let chao222 = LiuChao.abc.rawValue
let chao2242 = LiuChao.liuchao1.rawValue
LiuChao.abc.jianDanGuoLv()

if let row = LiuChao.init(rawValue: 3) {
    row.jianDanGuoLv()
}

//枚舉的另一種情況
enum ServerResponse {
    case result(String, String)
    case failure(String)
}

let success = ServerResponse.result("6:00 am", "8:09 pm")
let failure = ServerResponse.failure("Out of cheese.")

switch success {
case let .result(sunrise, sunset):
    print("Sunrise is at \(sunrise) and sunset is at \(sunset).")
case let .failure(message):
    print("Failure...  \(message)")
}

//用 typealias 關(guān)鍵字定義類型別名。一旦為類型創(chuàng)建了一個別名晤碘,你就可以在任何使用原始名字的地方使用這個別名褂微。
typealias AudioSample = UInt16

//結(jié)構(gòu)體
struct LiuChao333 {
    var name: String
    var age: Int

    func nameAgeStringResult() -> String {

        return "\(name),\(age)"
    }
}

let naage = LiuChao333.init(name: "liuchao", age: 23)
naage.nameAgeStringResult()


//Protocols and Extensions   針對結(jié)構(gòu)體和枚舉 實例方法中修改屬性值,可以在方法定義前添加關(guān)鍵字mutating
protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}

class SimpleClass: ExampleProtocol {

    var simpleDescription: String = "this is a simple description"

    func adjust() {
        simpleDescription += "yes yes yes"
    }
}
let simpaleclass = SimpleClass()
simpaleclass.adjust()
simpaleclass.simpleDescription

struct SimpleStructure: ExampleProtocol {
    var simpleDescription: String = "A simple structure"
    var anotherProperty: Int = 69105
    mutating func adjust() {
        simpleDescription += " (adjusted)"
    }
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription


extension Int: ExampleProtocol {
    var simpleDescription: String {
        return "The number \(self)"
    }
    mutating func adjust() {
        self += 42
    }
}
print(7.simpleDescription)

let protocolValue: ExampleProtocol = b
print(protocolValue.simpleDescription)
//print(protocolValue.anotherProperty)

// 錯誤處理
enum PrinterError: Error {
    case outOfPaper
    case onToner
    case onFire
}

//如果在函數(shù)中拋出錯誤  函數(shù)會立刻返回 調(diào)用函數(shù)會提示錯誤
func send(job: Int, toPrinter printerName: String) throws -> String {
    if printerName == "funnys" {
        throw PrinterError.outOfPaper
    }
    return "嘿嘿  不是我"
}
try send(job: 3, toPrinter: "fundnys")


//在do 內(nèi)放可能引發(fā)錯誤的代碼  catch 內(nèi)可以打印錯誤的名字
do {
    try send(job: 3, toPrinter: "funny")
} catch let printerError as  PrinterError {
    print(printerError)
}

//處理錯誤的另一種方式是try园爷?將結(jié)果轉(zhuǎn)為可選的宠蚂,
let printerResult = try? send(job: 2, toPrinter: "funnys")
print(printerResult ?? "dede")

//先fridgeIsOpen = true,然后是函數(shù)體正常的流程腮介,最后在 return 之前執(zhí)行 fridgeIsOpen = false,defer一個很適合的使用場景就是用來做清理工作
var fridgeIsOpen = false
let fridgeContent = ["milk", "eggs", "leftovers"]


func fridgeContains(_ food: String) -> Bool {
    fridgeIsOpen = true
    defer {
        fridgeIsOpen = false
    }

    let result = fridgeContent.contains(food)
    return result
}
fridgeContains("milk")
print(fridgeIsOpen)

//泛型,在尖括號里寫一個名字來創(chuàng)建一個泛型函數(shù)或者類型端衰。適用于類叠洗,枚舉和結(jié)構(gòu)體

func repeatItem<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] {
    var result = [Item]()

    for _ in 0..<numberOfTimes {
        result.append(item)
    }
    return result
}
repeatItem(repeating: "ItemItems", numberOfTimes: 4)

//重新實現(xiàn) Swift 標(biāo)準(zhǔn)庫中的可選類型
enum OptionalValue<Wrapped> {
    case none
    case some(Wrapped)
}
var possibleValue: OptionalValue<Int> = .none
possibleValue = .some(100)


//where 一般用作條件判斷,確認實現(xiàn)了什么才執(zhí)行函數(shù)體旅东,比如下面灭抑,確認T.Element實現(xiàn)了 Equatable協(xié)議,并且T.Element == U.Element
//T.Element 表示序列元素的類型 比較的是元素的類型相等 比如[1, 2, 3]的元素類型是 Int
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> Bool
    where T.Element: Equatable, T.Element == U.Element
{
    for lhsItem in lhs {
        for rhsItem in rhs {
            if lhsItem == rhsItem {
                return true
            }
        }
    }
    return false
}
anyCommonElements([1, 2, 3], [3])

//元組
let http404Error = (404,"Not Found")
http404Error.0
http404Error.1

//必須元素的數(shù)量一致
let (statusCode,statusString) = http404Error
print(statusCode)
print(statusString)
let (statusCode1,_) = http404Error

//也可以單獨命名,但是必須通過訪問名字來獲取元素
let httpError1 = (statuscode2: 200, statusString2: "OK")
httpError1.statuscode2
httpError1.statusString2

//斷言,可在debug模式下運行抵代,在release模式下不運行
let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
//針對代碼已經(jīng)檢查了條件
assertionFailure(_:file:line:)

//先決條件 precondition腾节,在debug和release下都運行
precondition(index > 0, "Index must be greater than zero.")
//針對代碼已經(jīng)檢查了條件
preconditionFailure(_:file:line:)

//fatalError函數(shù)一定會終止執(zhí)行,不管在什么情況下都會
fatalError(_:file:line:) 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子案腺,更是在濱河造成了極大的恐慌庆冕,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件劈榨,死亡現(xiàn)場離奇詭異访递,居然都是意外死亡,警方通過查閱死者的電腦和手機同辣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門拷姿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人旱函,你說我怎么就攤上這事响巢。” “怎么了棒妨?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵踪古,是天一觀的道長。 經(jīng)常有香客問我靶衍,道長灾炭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任颅眶,我火速辦了婚禮蜈出,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘涛酗。我一直安慰自己铡原,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布商叹。 她就那樣靜靜地躺著燕刻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪剖笙。 梳的紋絲不亂的頭發(fā)上卵洗,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機與錄音弥咪,去河邊找鬼过蹂。 笑死,一個胖子當(dāng)著我的面吹牛聚至,可吹牛的內(nèi)容都是我干的酷勺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼扳躬,長吁一口氣:“原來是場噩夢啊……” “哼脆诉!你這毒婦竟也來了甚亭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤击胜,失蹤者是張志新(化名)和其女友劉穎亏狰,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體潜的,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡骚揍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了啰挪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片信不。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖亡呵,靈堂內(nèi)的尸體忽然破棺而出抽活,到底是詐尸還是另有隱情,我是刑警寧澤锰什,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布下硕,位于F島的核電站,受9級特大地震影響汁胆,放射性物質(zhì)發(fā)生泄漏梭姓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一嫩码、第九天 我趴在偏房一處隱蔽的房頂上張望誉尖。 院中可真熱鬧,春花似錦铸题、人聲如沸铡恕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽探熔。三九已至,卻和暖如春烘挫,著一層夾襖步出監(jiān)牢的瞬間诀艰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工饮六, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留其垄,地道東北人。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓喜滨,卻偏偏與公主長得像捉捅,于是被迫代替她去往敵國和親撤防。 傳聞我的和親對象是個殘疾皇子虽风,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 更多整理資料盡在??一平米小站 變量和常量 運算符 可選項 條件語句 循環(huán) 字符串 元組 數(shù)組 字典 10-對象和類 控件
    leiyulingling閱讀 1,772評論 0 2
  • 我也不知道自己為什么開這篇文棒口,只是坐在這里別提綱的時候忽然發(fā)現(xiàn)好久沒有好好愛過自己了,不知道什么辜膝,最近真的好累无牵,喜...
    離未央閱讀 352評論 0 1
  • 放假第二天 1:.公園晨練,去早市 2:上午洗棉衣厂抖,毛衣等 3:下午去按摩 走了10389步茎毁,完成每日一萬步目標(biāo)。
    心境如花閱讀 230評論 0 0
  • 平凡之人因為不能保持內(nèi)心的清靜,在生理上則形成心火上炎墙懂,腎水下流之“火水未濟”之象橡卤,此象是人體陰陽失和之象,...
    雙星道人閱讀 703評論 0 0
  • 清明小記 清明時節(jié)雨紛紛损搬,路上行人欲斷魂碧库。雨水如期而至,行人如期而歸巧勤。每年的清明嵌灰,一家老小都會來到這個熟悉而又陌...
    循環(huán)錄閱讀 112評論 0 1