swift string转int_swift中结构体和类的区别(值类型和引用类型的区别)
在swift中結構體和類有著更多的相同之處,在一般的使用中能夠做到互相替換。我們可以先看看官方文檔的描述:
Unlike other programming languages, Swift doesn’t require you to create separate interface and implementation files for custom structures and classes. In Swift, you define a structure or class in a single file, and the external interface to that class or structure is automatically made available for other code to use.
An instance of a class is traditionally known as anobject. However, Swift structures and classes are much closer in functionality than in other languages, and much of this chapter describes functionality that applies to instances ofeithera class or a structure type. Because of this, the more general terminstanceis used.
Comparing Structures and Classes
Structures and classes in Swift have many things in common. Both can:
- Define properties to store values
- Define methods to provide functionality
- Define subscripts to provide access to their values using subscript syntax
- Define initializers to set up their initial state
- Be extended to expand their functionality beyond a default implementation
- Conform to protocols to provide standard functionality of a certain kind
簡單翻譯過來就是:
與其他編程語言不同,Swift不需要為自定義結構體和類創建單獨的接口和實現文件。在Swift中,您在單個文件中定義一個結構體或類,該類或結構體的外部接口將自動提供給其他代碼使用。
類的實例傳統上稱為對象。然而,Swift結構體和類在功能上比在其他語言中更接近
比較結構和類
Swift中的結構體和類有很多共同點。都可以:
- 定義屬性來存儲值
- 定義方法來提供功能
- 定義下標以使用下標語法提供對其值的訪問
- 定義初始化器來設置它們的初始狀態
- 擴展以擴展其功能,使其超出默認實現
- 遵守協議以提供某種標準功能
結構體和類最大的區別就是結構體是值類型,類是引用類型。
這里提醒一下Swift值類型列表:
- 結構體
- 枚舉
- 元組(tuple)
- 基本類型(Int,Double,Bool等)
- 集合(Array, String, Dictionary, Set)
引用類型最常用的就是類和閉包。
在 Swift 中,值類型,存放在棧區;引用類型,存放在堆區。但是有些值類型,如字符串或數組,會間接地將項保存在堆中。所以它們是由引用類型支持的值類型。
Swift 中,值類型的賦值為深拷貝(Deep Copy),值語義(Value Semantics)即新對象和源對象是獨立的,當改變新對象的屬性,源對象不會受到影響,反之同理。
引用類型的賦值是淺拷貝(Shallow Copy),引用語義(Reference Semantics)即新對象和源對象的變量名不同,但其引用(指向的內存空間)是一樣的,因此當使用新對象操作其內部數據時,源對象的內部數據也會受到影響。
struct Boy {var name = "Lilei"var age = 12 } var boyA = Boy() print("boyA.name -> (boyA.name)")var boyB = boyA boyB.name = "Tom" print("boyA.name -> (boyA.name)")控制臺輸出結果為:boyA.name -> LileiboyA.name -> LileiBoy為結構體的時候更改boyB的name boyA.name 并沒有改變
class Boy: NSObject {var name = "Lilei"var age = 12 } var boyA = Boy() print("boyA.name -> (boyA.name)")var boyB = boyA boyB.name = "Tom" print("boyA.name -> (boyA.name)") print(Unmanaged.passUnretained(boyA).toOpaque()) print(Unmanaged.passUnretained(boyB).toOpaque())控制臺輸出結果為:boyA.name -> LileiboyA.name -> Tom0x0000600002e2b9e00x0000600002e2b9e0Boy為class的時候更改boyB的name boyA也會改變,同時boyA的地址和boyB的地址相同可見在class中拷貝為指針拷貝,從中即可發現,兩個變量指向的是同一塊內存空間。
在swift4.0中 可以用==來判斷兩個對象是否是同一個對象
if boyA == boyB {print("boyA == boyB")} 控制臺輸出結果為:boyA == boyB嵌套類型
在使用過程中會存在嵌套的情況
值類型嵌套值類型:
struct Boy {var name = "Lilei"var age = 12var dog = Dog()}struct Dog {var weight = 40var name = "littleDog"} var boyA = Boy() var boyB = boyAboyB.name = "Tom" boyB.dog.name = "bigDog" boyB.dog.weight = 100print(boyA,boyA.dog) print(boyB,boyB.dog)控制臺輸出:Boy(name: "Lilei", age: 12, dog: swift_test.Dog(weight: 40, name: "littleDog")) Dog(weight: 40, name: "littleDog")Boy(name: "Tom", age: 12, dog: swift_test.Dog(weight: 100, name: "bigDog")) Dog(weight: 100, name: "bigDog")結構體嵌套結構體,很顯然賦值時創建了新的變量,兩者是獨立的,嵌套的值類型變量也會創建新的變量,這兩者也是獨立的。boyA和boyB 不同,dogA和dogB也不同
值類型嵌套引用類型:
把Dog改成Class
struct Boy {var name = "Lilei"var age = 12var dog = Dog() }class Dog:NSObject {var weight = 40var name = "littleDog" } var boyA = Boy() var boyB = boyA boyB.name = "Tom" boyB.dog.name = "bigDog" boyB.dog.weight = 100print(boyA,boyA.dog,boyA.dog.name) print(boyB,boyB.dog,boyB.dog.name) 控制臺輸出結果:Boy(name: "Lilei", age: 12, dog: <swift_test.Dog: 0x600001d110e0>) <swift_test.Dog: 0x600001d110e0> bigDogBoy(name: "Tom", age: 12, dog: <swift_test.Dog: 0x600001d110e0>) <swift_test.Dog: 0x600001d110e0> bigDog可以看出boyB發生了變化,boyB的dog和boyA的dog為同一個對象,值類型嵌套引用類型時,賦值時創建了新的變量,兩者是獨立的,但嵌套的引用類型指向的是同一塊內存空間,當改變值類型內部嵌套的引用類型變量值時(除了重新初始化),其他對象的該屬性也會隨之改變。
引用類型嵌套值類型:
Boy改成class,Dog為struct
class Boy: NSObject {var name = "Lilei"var age = 12var dog = Dog() }struct Dog {var weight = 40var name = "littleDog" } var boyA = Boy() var boyB = boyA boyB.name = "Tom" boyB.dog.name = "bigDog" boyB.dog.weight = 100print(boyA,boyA.dog,boyA.dog.name) print(boyB,boyB.dog,boyB.dog.name) 控制臺輸出:<swift_test.Boy: 0x600003853480> Dog(weight: 100, name: "bigDog") bigDog<swift_test.Boy: 0x600003853480> Dog(weight: 100, name: "bigDog") bigDog引用類型嵌套值類型時,賦值時創建了新的變量,但是新變量和源變量指向同一塊內存,因此改變源變量的內部值,會影響到其他變量的值。
引用類型嵌套引用類型:
class Boy: NSObject {var name = "Lilei"var age = 12var dog = Dog() }struct Dog {var weight = 40var name = "littleDog" } var boyA = Boy() var boyB = boyA boyB.name = "Tom" boyB.dog.name = "bigDog" boyB.dog.weight = 100print(boyA,boyA.dog,boyA.dog.name) print(boyB,boyB.dog,boyB.dog.name) 控制臺輸出:<swift_test.Boy: 0x6000029c4120> <swift_test.Dog: 0x6000027d0fa0> bigDog<swift_test.Boy: 0x6000029c4120> <swift_test.Dog: 0x6000027d0fa0> bigDog引用類型嵌套引用類型時,賦值時創建了新的變量,但是新變量和源變量指向同一塊內存,內部引用類型變量也指向同一塊內存地址,改變引用類型嵌套的引用類型的值,也會影響到其他變量的值。
總結:
類和結構體的選擇:
- 該數據結構的主要目的是用來封裝少量相關簡單數據值;
- 有理由預計該數據結構的實例在被賦值或傳遞時,封裝的數據將會被拷貝而不是被引用;
- 該數據結構中儲存的值類型屬性,也應該被拷貝,而不是被引用;
- 該數據結構不需要去繼承另一個既有類型的屬性或者行為。
當有上面的一種情況或多種情況請選擇結構體,結構體比類更簡單,也就是更輕便。
總結
以上是生活随笔為你收集整理的swift string转int_swift中结构体和类的区别(值类型和引用类型的区别)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python不能分配给操作员_Pytho
- 下一篇: 开发文档模板_需求文档模板一堆什么样的适