swift中結構體和類的區別(值類型和引用類型的區別)?
一、swift中結構體和類的區別
值類型 vs 引用類型
結構體是值類型,實際上,Swift 中所有的基本類型:整數,浮點數,布爾量,字符串,數組和字典,還有枚舉,都是值類型,并且都以結構體的形式在后臺實現。
這意味著字符串,數組和字典在被賦值到一個新的常量或變量,或者它被傳遞到一個函數或方法中的時候,其實是傳遞了值的拷貝。這不同于 OC 的 NSString,NSArray 和 NSDictionary,他們是類,屬于引用類型,賦值和傳遞都是引用。
值類型存儲的是值,賦值時都是進行值拷貝,相互之間不會影響。而引用類型存儲的是對象的內存地址,賦值時拷貝指針,都是指向同一個對象,即同一塊內存空間。
1、結構體是值類型
swift
復制代碼
struct Book {
??? var name: String
??? var high: Int
??? func turnToPage(page:Int) {
??????? print(“turn to page \(page)”)
??? }
}
var s = Book(name: “程序員的自我修養”, high: 8)
var s1 = s
s1.high = 10
print(s.high, s1.high) // 8 10
這段代碼中初始化結構體high為18,賦值給s1時拷貝整個結構體,相當于s1是一個新的結構體,修改s1的high為10后,s的age仍然是8,s和s1互不影響。
通過 lldb 調試, 也能夠看出 s 和 s1 是不同的結構體. 一個在 0x100008080, 一個在 0x100008098.
swift
復制代碼
(lldb) frame variable -L s
0x0000000100008080: (SwiftTest.Book) s = {
0x0000000100008080:?? name = “程序員的自我修養”
0x0000000100008090:?? high = 8
}
(lldb) frame variable -L s1
0x0000000100008098: (SwiftTest.Book) s1 = {
0x0000000100008098:?? name = “程序員的自我修養”
0x00000001000080a8:?? high = 10
}
2、類是引用類型
swift
復制代碼
class Person {
??? var age: Int = 22
??? var name: String?
??? init(_ age: Int, _ name: String) {
??????? self.age = age
??????? self.name = name
??? }
??? func eat(food:String) {
??????? print(“eat \(food)”)
??? }
??? func jump() {
??????? print(“jump”)
??? }
}
var c = Person(22, “jack”)
var c1 = c
c1.age = 30
print(c.age, c1.age) // 30 30
如果是類,c1=c的時候拷貝指針,產生了一個新的引用,但都指向同一個對象,修改c1的age為30后,c的age也會變成30。
swift
復制代碼
(lldb) frame variable -L c
scalar: (SwiftTest.Person) c = 0x0000000100679af0 {
0x0000000100679b00:?? age = 30
0x0000000100679b08:?? name = “jack”
}
(lldb) frame variable -L c1
scalar: (SwiftTest.Person) c1 = 0x0000000100679af0 {
0x0000000100679b00:?? age = 30
0x0000000100679b08:?? name = “jack”
}
(lldb) cat address 0x0000000100679af0
address:0x0000000100679af0, (String) $R1 = “0x100679af0 heap pointer, (0x30 bytes), zone: 0x7fff8076a000”
通過lldb調試,發現類的實例 c 和 c1 實際上是同一個對象, 再通過自定義命令 address 可以得出這個對象是在 heap 堆上.
而 c 和 c1 本身是2個不同的指針, 他們里面都存的是 0x0000000100679af0 這個地址.
swift
復制代碼
(lldb) po withUnSAFePointer(to: &c, {print($0)})
0x0000000100008298
0 elements
(lldb) po withUnSAFePointer(to: &c1, {print($0)})
0x00000001000082a0
0 elements
延伸閱讀:
二、SIL是什么
Swift Intermediate Language,Swift高級中間語言,Swift 編譯過程引入SIL有以下優點:
完全保留程序的語義既能進行代碼的生成,又能進行代碼分析處在編譯管線的主通道 (hot path)架起橋梁連接源碼與LLVM,減少源碼與LLVM之間的抽象鴻溝SIL會對Swift進行高級別的語意分析和優化。像LLVM IR一樣,也具有諸如Module,Function和BasicBlock之類的結構。與LLVM IR不同,它具有更豐富的類型系統,有關循環和錯誤處理的信息仍然保留,并且虛函數表和類型信息以結構化形式保留。它旨在保留Swift的含義,以實現強大的錯誤檢測,內存管理等高級優化。

猜你喜歡LIKE
相關推薦HOT
更多>>
mysql怎么查看連接池是否已滿?
一、mysql怎么查看連接池是否已滿1.查看連接數配置(MySQL服務器允許的最大連接數16384)show variables like ‘%max_connections%’2.查看當前...詳情>>
2023-10-17 21:20:19
什么是職場情商,如何提高?
什么是情商?情商是一個 20 世紀 90 年代作為學術話題出現的概念,并迅速成為商業心理學和職場動態研究的重要組成部分。它通常被稱為 EQ(情商...詳情>>
2023-10-17 20:16:30
vector, list, map等容器使用場合是什么?
一、vector, list, map等容器使用場合vector適用于對象簡單,變化較小,并且頻繁隨機訪問的場景。list適用經常進行插入和刪除并且不經常隨機訪...詳情>>
2023-10-17 19:45:03
數據挖掘中涉及的關聯規則在實際生活中的應用有哪些?
一、數據挖掘中涉及的關聯規則在實際生活中的應用關于關聯規則分析,這篇文章可以認真學習一下,講的比較全面,關聯規則分析還在零售、快消、電...詳情>>
2023-10-17 18:40:06熱門推薦
sql server2012r2所在服務器做端口限制,需要開放什么端口才能繼續訪問數據庫?
沸Oracle有什么優勢和劣勢?
熱數據庫聚集索引非聚集索引實現上有哪些區別?
熱數據庫(如oracle、mysql)及編程語言(php、python、perl、lisp)的區別?
新CSS 隱藏頁面元素有哪些方法?
除了cx_Oracle,python還可以通過什么方式訪問Oracle數據庫?
SQL開啟事務處理的語句 START TRANSACTION 和BEGIN TRAN的區別?
Android適配你需要學習哪些?
開發web應用,好的開發流程是怎么樣的?
為什么說Gradle是Android進階繞不去的坎?
mysql怎么查看連接池是否已滿?
WHERE中有很多IN判斷怎么提速?
軟件開發要遵循哪些事項?
有了innodb buffer pool為什么要有redis?
技術干貨






