主頁 > 移動端開發 > Swift 進階(一)基礎語法

Swift 進階(一)基礎語法

2021-04-02 06:45:00 移動端開發

Swift簡介

在學習Swift之前,我們先來了解下什么是Swift

Swift是Apple在2014年6月WWDC發布的全新編程語言,中文名和LOGO是”雨燕“

Swift之父是Chris Lattner,也是Clang編譯器的作者,LLVM專案的主要發起人

Swift版本

Swift歷時七年,從Swift 1.*更新到Swift 5.*,經歷了多次重大改變,ABI終于穩定

API(Application Programming Interface):應用程式編程介面

  • 源代碼和庫之間的介面

ABI(Application Binary Interface):應用程式二進制介面

  • 應用程式和作業系統之間的底層介面
  • 涉及的內容有:目標檔案格式、資料型別的大小/布局/對齊,函式呼叫約定等

Swift是完全開源的,下載地址:https://github.com/apple/swift

Swift編譯原理

LLVM編譯器

LLVM編譯器一般分為前端和后端

  • 前端:主要進行詞法分析,生成語法樹
  • 后端:生成對應平臺的二進制代碼

編譯流程

我們知道OC的前端是通過Clang進行編譯的,Swift的前端是通過swiftc來編譯的

不同語言的前端可能不同,但最終都會通過編譯器的后端生成對應平臺的二進制代碼

-w727

整個編譯流程如下圖所示

-w525

  • Swift Code:我們撰寫的Swift代碼
  • Swift AST:Swift語法樹
  • Raw Swift IL:Swift特有的中間代碼
  • Canonical Swift IL:更簡潔的Swift特有的中間代碼
  • LLVM IR:LLVM的中間代碼
  • Assembly:匯編代碼
  • Executable:二進制代碼

關于Swift編譯流程的詳細講解可以參考以下網址:https://swift.org/swift-compiler/#compiler-architecture

swiftc

我們打開終端,輸入swiftc -help,會列印出相關指令,這也說明了swiftc已經存在于Xcode中

-w890

我們可以在應用程式中找到Xcode,然后右鍵顯示包內容,通過該路徑找到swiftc

路徑:/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

-w1175
-w788

swiftc的基本操作演練

下面我們可以通過一些swiftc的一些基本操作來了解

1.我們先新建一個Swift的命令列專案

-w1399
-w1076

2.然后打開終端,cdmain.swift路徑

-w890

3.然后我們輸入swiftc -dump-ast main.swift,來查看下生成的語法樹

-w890

4.我們還可以輸入swiftc -emit-sil main.swift生成最簡潔的SIL代碼

-w890

5.我們還可以輸入swiftc -emit-ir main.swift生成LLVM IR中間代碼

-w890

6.我們還可以輸入swiftc -emit-assembly main.swift生成匯編代碼

-w890

Swift基礎語法

Swift中列印輸入:print("Hello World")

Swift中一句代碼是可以省略分號的,但是如果多句代碼寫在一行,需要用分號隔開

Swift不用撰寫main函式,會以全域范圍內的首句可執行代碼作為入口來執行

通過反匯編我們可以看到底層會執行main函式

-w1084

常量和變數

常量:

1.用let定義常量,常量只能賦值一次

不用特意指明型別,編譯器會自動進行推斷

let a: Int = 10
let b = 20

2.它的值不要求在編譯程序中確定,但使用之前必須賦值一次

這樣寫確定了a的型別,之后再去賦值,也不會報錯

let a: Int
a = 10

用函式給常量賦值也可以,函式是在運行時才會確定值的,所以只要保證使用之前賦值了就行

func getNumber() -> Int {
    return 10
}

let a: Int
a = getNumber()

如果沒有給a確定型別,也沒有一開始定義的時候賦值,就會像下面這樣報錯

-w643

變數:

1.用var定義變數

var b = 20
b = 30

2.常量、變數在初始化之前,都不能使用

-w644

注釋

1.Swift中有單行注釋和多行注釋

注釋之間嵌套也沒有問題

// 單行注釋

/*
 多行注釋
 /*
 多行注釋
 */
 
 /*
 // 注釋嵌套
 */

2.Playground里的注釋支持Markup語法(同Markdown)

Markup語法只在Playground里有效,在專案中無效

//: # 一級標題

/*:
 ## 基礎語法
 */

可以通過Editor -> Show Raw Markup來預覽

-w299

預覽的效果如下

-w369

識別符號

1.識別符號(比如常量名、變數名、函式名)幾乎可以使用任何字符

let ?? = 5
var ?? = 10

func ??() {
    
}

識別符號不能以數字開頭,不能包含空白字符、制表符、箭頭等特殊字符

-w649

常見資料型別

常見型別

  • 值型別
    • 列舉(enum): Optional
    • 結構體(struct): Bool、Double、Float、Int、Character、String、Array、Dictionary、Set
  • 參考型別
    • 類(class)

可以通過command+control進入到該型別的API中查看

例如Int型別

-w757

整數型別

整數型別:Int8、Int16、Int32、Int64、UInt8、UInt16、UInt32、UInt64

在32bit平臺,Int等于Int32;在64bit平臺,Int等于Int64

整數的最值:UInt8.max,Int16.min

一般情況下,都是直接使用Int即可

let a: Int8 = 5

浮點型別

Float:32位,精度只有6位

Double:64位,精度至少15位

浮點型不指明型別默認就是Double

let a: Float = 2.0
let b = 3.0

字面量

字面量就是指這個量本身,就是一個固定值的表示法

下面這些都是字面量

Bool布爾

一般用Bool型別來表示是否的判斷,是為true,否為false

let bool = true 
字串、字符

字串的寫法

let string = "hello"

字符型別要寫上Character,否則會被認為是字串

字符可存盤ASCII字符、Unicode字符

let character: Character = "a"
整數

不同進制的表示法

  • 二進制以0b開頭
  • 八進制以0o開頭
  • 十六進制以0x開頭
let intDecimal = 17 // 十進制
let intBinary = 0b10001 // 二進制
let intOctal = 0o21 // 八進制
let intHexadecimal = 0x11 // 十六進制
浮點數
let doubleDecimal = 125.0 // 十進制
let doubleDecimal2 = 1.25e2 // 也是125.0的另一種寫法,表示1.25乘以10的二次方

let doubleDecimal3 = 0.0125
let doubleDecimal4 = 1.25e-2 // 也是0.0125的另一種寫法,表示1.25乘以10的負二次方

let doubleHexadecimal1 = 0xFp2 // 十六進制,意味著15*2^2(15乘以2的二次方),相當于十進制的60
let doubleHexadecimal2 = 0xFp-2 //十六進制,意味著15*2^-2(15乘以2的負二次方),相當于十進制的3.75

整數和浮點數可以添加額外的零或者下劃線來增強可讀性

let num = 10_0000
let price = 1_000.000_000_1
let decimal = 000123.456
陣列
let array = [1, 2, 3, 4]
字典
let dictionary = ["age" : 18,
                  "height" : 1.75]

型別轉換

整數轉換

let int1: UInt16 = 2_000
let int2: UInt8 = 1
let int3 = int1 + UInt16(int2)

整數、浮點數轉換

let int = 3
let double = 0.1415926
let pi = Double(int) + double
let intPi = Int(pi)

字面量可以直接相加,因為數字字面量本身沒有明確的型別

let result = 3 + 0.14159

元組(tuple)

元組是可以多種資料型別組合在一起

let http404Error = (404, "Not Found")
print("The status code is \(http404Error.0)")

// 可以分別把元組里的兩個值分別進行賦值
let (statusCode, statusMsg) = http404Error
print("The status code is \(statusCode)")

// 可以只給元組里的某一個值進行賦值
let (justTheStatusCode, _) = http404Error

// 可以在定義的時候給元組里面的值起名
let http200Status = (statusCode: 200, description: "ok")
print("The status code is \(http200Status.statusCode)")

流程控制

if-else

Swift里的if else后面的條件是可以省略小括號的,但大括號不可以省略

let age = 10

if age >= 22 {
    print("Get married")
} else if age >= 18 {
    print("Being a adult")
} else if age >= 7 {
    print("Go to school")
} else {
    print("Just a child")
}

if else后面的條件只能是Bool型別

-w718

while

var num = 5
while num > 0 {
	print("num is \(num)")
	// 列印了五次
}

repeat-while相當于C語言中的do-while

先執行一次,再判斷條件回圈

var num = -1
repeat {
	print("num is \(num)")
	// 列印了一次
} while num > 0

這里不用num--是因為Swift3開始,已經去掉了自增(++)、自減(--)運算子

for

1.閉區間運算子:a...b,相當于a <= 取值 <= b

// 第一種寫法
let names = ["Anna", "Alex", "Brian", "Jack"]
for i in 0...3 {
    print(names[i])
}
// 第二種寫法
let range = 0...3
for i in range {

}

// 第三種寫法
let a = 1
let b = 3
for i in a...b {

}

回圈里的i默認是let,如需要更改加上var

for var i in 0...3 {

}

不需要值的時候用_來表示

for _ in 0...3 {

}

2.半開區間運算子:a..<b,相當于a <= 取值 < b

for i in 0..<3 {

}

3.單側區間:讓一個區間朝一個方向盡可能的遠

for i in ...3 {

}

for _ in 3... {

}

4.區間運算子還可以用在陣列上

let names = ["Anna", "Alex", "Brian", "Jack"]

for name in names[0...3] {
    print(name)
}

for name in names[2...] {
    print(name)
}

for name in names[...2] {
    print(name)
}

for name in names[..<2] {
    print(name)
}

let range = ...5
range.contains(4)

5.區間的幾種型別

閉區間 ClosedRange<Int> 
1...3

半開區間 Range<Int>
 1..<3
 
單側區間 PartialRangeThrough<Int>
...3

6.字符、字串也能使用區間運算子,但默認不能用在for-in

let stringRange1 = "cc"..."ff"
stringRange1.contains("cd")

let stringRange2 = "a"..."f"
stringRange2.contains("c")

let characterRange:ClosedRange<Character> = "\0"..."~"
characterRange.contains("G")

7.帶間隔的區間值

let hours = 10
let hourInterval = 2

// tickmark的取值,從4開始,累加2,不超過10
for tickmark in stride(from: 4, through: hours, by: hourInterval) {
	print(tickmark)
	// 4,6,8,10
}

switch

使用同C語言的switch,不同的是case、default后面不寫大括號{}

var number = 1

switch number {
case 1:
    print("number is 1")
    break
case 2:
    print("number is 2")
    break
default:
    print("number is other")
    break
}

默認不寫case,并不會貫穿到后面的條件

var number = 1

switch number {
case 1:
    print("number is 1")
case 2:
    print("number is 2")
default:
    print("number is other")
}

使用fallthrough可以實作貫穿效果

var number = 1

switch number {
case 1:
    print("number is 1")
    fallthrough
case 2:
    print("number is 2")
default:
    print("number is other")
}

// 會同時列印number is 1,number is 2

switch必須要保證能處理所有情況

注意:像判斷number的值,要考慮到所有整數的條件,如果不要判斷全部情況,加上default就可以了

-w722

case、default后面至少要有一條陳述句

如果不想做任何事,加個break即可

var number = 1

switch number {
case 1:
    print("number is 1")
case 2:
    break
default:
    break
}

如果能保證已處理所有情況,也可以不必使用default

enum Answer { case right, wrong }

let answer = Answer.right

switch answer {
case .right:
    print("right")
case .wrong:
    print("wrong")
}

switch也支持CharacterString型別

let string = "Jack"

switch string {
case "Jack":
    fallthrough
case "Rose":
    print(string)
default:
    break
}

switch可以同時判斷多個條件

let string = "Jack"

switch string {
case "Jack", "Rose":
    print(string)
default:
    break
}

let character: Character = "a"

switch character {
case "a", "A":
    print(character)
default:
    break
}

switch也支持區間匹配和元組匹配

let count = 62

switch count {
case 0:
    print("none")
case 1..<5:
    print("a few")
case 5..<12:
    print("several")
case 12..<100:
    print("dozens of")
default:
    print("many")
}

可以使用下劃線忽略某個值

let point = (1, 1)
switch point: {
case (2, 2):
	print("1")
case (_, 0):
	print("2")
case (-2...2, 0...):
	print("3")
} 

值系結,必要時let也可以改成var

let point = (2, 0)
switch point: {
case (let x, 0):
	print(x)
case (0, let y):
	print("2")
case let (x, y):
	print("3")
} 

where

一般where用來結合條件陳述句進行過濾

let point = (1, -1)
switch point {
case let (x, y) where x == y:
    print("on the line x == y")
case let (x, y) where x == -y:
    print("on the line x == -y")
case let (x, y):
    print("\(x), \(y) is just some arbitrary point")
}

for i in 0...5 where i == 3 {
    print(i)
}

標簽陳述句

outer來標識回圈跳出的條件

outer: for i in 1...4 {
	for k in 1...4 {
		if k == 3 {
			continue outer
		}
		
		if i == 3 {
			break outer
		}
	}
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/271192.html

標籤:iOS

上一篇:edittext,bmob短信驗證講解

下一篇:iOS-審核4.3入坑(已出坑)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more