swift string转int_swift中结构体和类的区别(值类型和引用类型的区别)
在swift中結(jié)構(gòu)體和類有著更多的相同之處,在一般的使用中能夠做到互相替換。我們可以先看看官方文檔的描述:
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不需要為自定義結(jié)構(gòu)體和類創(chuàng)建單獨(dú)的接口和實(shí)現(xiàn)文件。在Swift中,您在單個(gè)文件中定義一個(gè)結(jié)構(gòu)體或類,該類或結(jié)構(gòu)體的外部接口將自動(dòng)提供給其他代碼使用。
類的實(shí)例傳統(tǒng)上稱為對象。然而,Swift結(jié)構(gòu)體和類在功能上比在其他語言中更接近
比較結(jié)構(gòu)和類
Swift中的結(jié)構(gòu)體和類有很多共同點(diǎn)。都可以:
- 定義屬性來存儲值
- 定義方法來提供功能
- 定義下標(biāo)以使用下標(biāo)語法提供對其值的訪問
- 定義初始化器來設(shè)置它們的初始狀態(tài)
- 擴(kuò)展以擴(kuò)展其功能,使其超出默認(rèn)實(shí)現(xiàn)
- 遵守協(xié)議以提供某種標(biāo)準(zhǔn)功能
結(jié)構(gòu)體和類最大的區(qū)別就是結(jié)構(gòu)體是值類型,類是引用類型。
這里提醒一下Swift值類型列表:
- 結(jié)構(gòu)體
- 枚舉
- 元組(tuple)
- 基本類型(Int,Double,Bool等)
- 集合(Array, String, Dictionary, Set)
引用類型最常用的就是類和閉包。
在 Swift 中,值類型,存放在棧區(qū);引用類型,存放在堆區(qū)。但是有些值類型,如字符串或數(shù)組,會(huì)間接地將項(xiàng)保存在堆中。所以它們是由引用類型支持的值類型。
Swift 中,值類型的賦值為深拷貝(Deep Copy),值語義(Value Semantics)即新對象和源對象是獨(dú)立的,當(dāng)改變新對象的屬性,源對象不會(huì)受到影響,反之同理。
引用類型的賦值是淺拷貝(Shallow Copy),引用語義(Reference Semantics)即新對象和源對象的變量名不同,但其引用(指向的內(nèi)存空間)是一樣的,因此當(dāng)使用新對象操作其內(nèi)部數(shù)據(jù)時(shí),源對象的內(nèi)部數(shù)據(jù)也會(huì)受到影響。
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)")控制臺輸出結(jié)果為:boyA.name -> LileiboyA.name -> LileiBoy為結(jié)構(gòu)體的時(shí)候更改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())控制臺輸出結(jié)果為:boyA.name -> LileiboyA.name -> Tom0x0000600002e2b9e00x0000600002e2b9e0Boy為class的時(shí)候更改boyB的name boyA也會(huì)改變,同時(shí)boyA的地址和boyB的地址相同可見在class中拷貝為指針拷貝,從中即可發(fā)現(xiàn),兩個(gè)變量指向的是同一塊內(nèi)存空間。
在swift4.0中 可以用==來判斷兩個(gè)對象是否是同一個(gè)對象
if boyA == boyB {print("boyA == boyB")} 控制臺輸出結(jié)果為:boyA == boyB嵌套類型
在使用過程中會(huì)存在嵌套的情況
值類型嵌套值類型:
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")結(jié)構(gòu)體嵌套結(jié)構(gòu)體,很顯然賦值時(shí)創(chuàng)建了新的變量,兩者是獨(dú)立的,嵌套的值類型變量也會(huì)創(chuàng)建新的變量,這兩者也是獨(dú)立的。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) 控制臺輸出結(jié)果: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發(fā)生了變化,boyB的dog和boyA的dog為同一個(gè)對象,值類型嵌套引用類型時(shí),賦值時(shí)創(chuàng)建了新的變量,兩者是獨(dú)立的,但嵌套的引用類型指向的是同一塊內(nèi)存空間,當(dāng)改變值類型內(nèi)部嵌套的引用類型變量值時(shí)(除了重新初始化),其他對象的該屬性也會(huì)隨之改變。
引用類型嵌套值類型:
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引用類型嵌套值類型時(shí),賦值時(shí)創(chuàng)建了新的變量,但是新變量和源變量指向同一塊內(nèi)存,因此改變源變量的內(nèi)部值,會(huì)影響到其他變量的值。
引用類型嵌套引用類型:
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引用類型嵌套引用類型時(shí),賦值時(shí)創(chuàng)建了新的變量,但是新變量和源變量指向同一塊內(nèi)存,內(nèi)部引用類型變量也指向同一塊內(nèi)存地址,改變引用類型嵌套的引用類型的值,也會(huì)影響到其他變量的值。
總結(jié):
類和結(jié)構(gòu)體的選擇:
- 該數(shù)據(jù)結(jié)構(gòu)的主要目的是用來封裝少量相關(guān)簡單數(shù)據(jù)值;
- 有理由預(yù)計(jì)該數(shù)據(jù)結(jié)構(gòu)的實(shí)例在被賦值或傳遞時(shí),封裝的數(shù)據(jù)將會(huì)被拷貝而不是被引用;
- 該數(shù)據(jù)結(jié)構(gòu)中儲存的值類型屬性,也應(yīng)該被拷貝,而不是被引用;
- 該數(shù)據(jù)結(jié)構(gòu)不需要去繼承另一個(gè)既有類型的屬性或者行為。
當(dāng)有上面的一種情況或多種情況請選擇結(jié)構(gòu)體,結(jié)構(gòu)體比類更簡單,也就是更輕便。
總結(jié)
以上是生活随笔為你收集整理的swift string转int_swift中结构体和类的区别(值类型和引用类型的区别)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python不能分配给操作员_Pytho
- 下一篇: 开发文档模板_需求文档模板一堆什么样的适