Swift~基礎(chǔ)語(yǔ)法、匯編初探

本文源自本人的學(xué)習(xí)記錄整理與理解,其中參考閱讀了部分優(yōu)秀的博客和書(shū)籍,盡量以通俗簡(jiǎn)單的語(yǔ)句轉(zhuǎn)述。引用到的地方如有遺漏或未能一一列舉原文出處還望見(jiàn)諒與指出,另文章內(nèi)容如有不妥之處還望指教,萬(wàn)分感謝。

Swift的編譯與OC對(duì)比

WX20200513-191118.png

可以看出:OC編譯器前端是Clang ,而Swift的編譯器前端是swiftc

Swift的編譯過(guò)程

Swift的編譯過(guò)程.png

如何生成Swift的抽象語(yǔ)法樹(shù) ?

終端打印:swift -dump-ast main.swift

終端導(dǎo)出到文件:swift -dump-ast main.swift -o main.ast

main.ast : 文件名和格式

示例.png

如何生成簡(jiǎn)潔的SIL代碼 ?

使用命令:swiftc -emit-sil main.swift

如何生成LLVM IR代碼 ?

使用命令:swiftc -emit-ir main.swift
導(dǎo)出:swiftc -emit-ir main.swift -o main.ll

如何生成匯編代碼 ?

使用命令:swiftc -emit-assembly main.swift
導(dǎo)出: swiftc -emit-assembly main.swift -o main.s

對(duì)匯編代碼進(jìn)行分析,可以真正掌握編程語(yǔ)言的本質(zhì)!?。?/p>

基礎(chǔ)語(yǔ)法

  • 不用編寫(xiě)main函數(shù),Swift將全局范圍內(nèi)的首句可執(zhí)行代碼作為程序入口;但依然還是有main函數(shù)的,只不過(guò)不用我們寫(xiě)
  • 一句代碼尾部可以省略分號(hào)(;),多句代碼寫(xiě)到同一行時(shí)必須用分號(hào)(;)隔開(kāi)
  • var定義變量,let定義常量,編譯器能自動(dòng)推斷出變量或常量的類型
  • Playground可以快速預(yù)覽代碼效果,是學(xué)習(xí)語(yǔ)法的好幫手
  • Command + Shift + Enter: 運(yùn)行整個(gè)Playground
  • Shift + Enter: 運(yùn)行截止到某一行代碼
自動(dòng)識(shí)別數(shù)據(jù)類型.png
可預(yù)覽代碼效果示例.png
  • liveView可以賦值給view, 也可以給一個(gè)vc
liveView.png
  • Playground支持添加多頁(yè)面

  • Playground支持markup語(yǔ)法,和markdown類似

  • 注意:markup只在Playground有效

語(yǔ)法.png
單行注釋寫(xiě)法---
// : 發(fā)飆妹

-----------

多行注釋寫(xiě)法
/*:
 ## 逍遙侯
 ### 城主
 */

//: [上一頁(yè)](@previous)
//: [下一頁(yè)](@next)

markup渲染.png
效果1.png
效果2.png
  • swift支持注釋多行嵌套
注釋多行嵌套.png

常量

  • 只能賦值一次,不允許第二次賦值
  • 它的值不要求在編譯時(shí)期確定,但使用之前必須賦值一次;一旦沒(méi)有賦值就使用,會(huì)直接報(bào)錯(cuò);從這一點(diǎn)上也體現(xiàn)出比OC安全,OC這種寫(xiě)法是不會(huì)報(bào)錯(cuò)的,只會(huì)警告??
  • oc語(yǔ)言是要求編譯時(shí)期必須確定常量的值
沒(méi)有賦值就使用,會(huì)直接報(bào)錯(cuò).png
let age int //可以不用直接賦值,給一個(gè)類型;后邊賦值也可以
age = 30
---------

var num = 20
num +=10

//num的值在運(yùn)行時(shí)才可以確定,賦值給一個(gè)常量。不會(huì)編譯報(bào)錯(cuò)
let age  = num

定義一個(gè)方法

/*
func:  表示定義一個(gè)方法
config:方法名
Int:返回值類型
*/

func config() -> Int {

return 10

}

標(biāo)識(shí)符

  • 標(biāo)識(shí)符(比如常量名、變量名、函數(shù)名)幾乎可以使用任何字符
  • 標(biāo)識(shí)符不能以數(shù)字開(kāi)頭,不能包含空白字符、制表符、箭頭等特殊字符
func ??() -> Int {

return 168

}

let ?? = “火箭”

常見(jiàn)數(shù)據(jù)類型

  • swift中的數(shù)據(jù)類型被分為兩大類:值類型、引用類型,不存在OC中的基本數(shù)據(jù)類型這樣的概念
常見(jiàn)數(shù)據(jù)類型.png

疑問(wèn):Int 為什么要被定義為一個(gè)結(jié)構(gòu)體 ?有什么優(yōu)勢(shì)

被定義為結(jié)構(gòu)體使用起來(lái)更加方便,都知道結(jié)構(gòu)體是可以擁有成員的,也就是說(shuō)int類型可以像OC對(duì)象一樣使用點(diǎn)語(yǔ)法。這樣開(kāi)發(fā)起來(lái)會(huì)更加的便捷 !比如想知道一個(gè)Int16的最大值,可以直接使用 Int16.max ; 說(shuō)白了就是 Int 可以調(diào)用方法,變的更加強(qiáng)大

字面量:直接寫(xiě)出的值就是字面量

//布爾
//true和false就是字面量
let bool = true //取反是false

-------------------------

//字符串

let string = "逍遙候"


//字符(可存儲(chǔ)ASCII字符、Unicode字符)
字符類型必須寫(xiě)清楚是 Character類型,因?yàn)樽址妥址际鞘褂秒p引號(hào)
let chstr: Character = "息"


字符類型必須寫(xiě)清楚是 Character 類型,因?yàn)樽址妥址际鞘褂?code>雙引號(hào)

  • 整數(shù)字面量
let intDecimal  = 17 //十進(jìn)制
let intBinary  = 0b10001 //二進(jìn)制
let intOctal  = 0o21 //八進(jìn)制
let intHex  = 0x11 //十六進(jìn)制

整數(shù)和浮點(diǎn)數(shù)可以添加額外的零或者添加下劃線來(lái)增強(qiáng)可讀性
比如:100_00000、1_000_000_111_000

  • 浮點(diǎn)數(shù)字面量

//十進(jìn)制 等價(jià)于1.25e2 -- > 1.25??10的2次方 ; 
// e :10 ;2:2次方
let doubleDecimal = 125.0 

//十六進(jìn)制 等價(jià)于15x2^2 相當(dāng)于十進(jìn)制的60
p: 代表乘以 ??

let doubleHexdecimal1 = 0xFp2 

//十六進(jìn)制 等價(jià)于15x2^-2(負(fù)二次方) 相當(dāng)于十進(jìn)制的60
let doubleHexdecimal2 = 0xFp-2 

  • 數(shù)組和字典

let array = [1,3,5,7,9]

let dictionary = ["age": 50, "hei":168]

字典和數(shù)組都使用中括號(hào)

  • 類型轉(zhuǎn)換

整數(shù)類型轉(zhuǎn)換,定義兩個(gè)不同類型的整數(shù),相加時(shí)需要把低類型的整數(shù)轉(zhuǎn)換成高類型的整數(shù)

let int1: UInt16 = 200
let int2:UInt8 = 2

let int3 = int1 + Uint16(int2)

整數(shù)和浮點(diǎn)數(shù)轉(zhuǎn)換, 需要把整數(shù)轉(zhuǎn)換成浮點(diǎn)數(shù)在做運(yùn)算


let int = 2
let double = 2.006

let pd = Double(int) + double

注意:有沒(méi)有發(fā)現(xiàn)常量名、變量名的定義是可以直接寫(xiě) int double 這是不會(huì)報(bào)錯(cuò)的哦

  • 數(shù)字字面量沒(méi)有明確類型之前可以相加,一旦明確類型就不能夠相加

let resu = 3 + 0.14159

元組 (tuple) : 由多種類型組合而成的數(shù)據(jù)類型

  • 元組和元組之間可以直接賦值

注意:元組不是結(jié)構(gòu)體,是兩種不同的數(shù)據(jù)結(jié)構(gòu)


//定義元組
let status = (200, "succeed")

//訪問(wèn)元組通過(guò)下標(biāo)
status.0
status.1

//元組間賦值
//接收兩個(gè)
let status(st, msg) = status
//只接收第一個(gè)的值
let status(st, _) = status

//定義元組同時(shí)定義名稱
let status = (sta: 200,  msg: "succeed")
//訪問(wèn)元組通過(guò)名稱
status.sta
status.msg

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

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

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