Swift中Class和Struct異同

2022-04-05 00:11:18 字數 3573 閱讀 9137

swift 中類和結構體有很多共同點。共同處在於:

與結構體相比,類還有如下的附加功能:

tip:類的物件是引用型別,而結構體是值型別。所以類的賦值是傳遞引用,結構體則是copy傳值,不是使用引用計數。

類和結構體有著類似的定義方式。我們通過關鍵字classstruct來分別表示類和結構體,並在一對大括號中定義它們的具體內容:

class someclass 

struct somestructure

注意

在定義乙個新類或者結構體的時候,實際上是定義了乙個新的 swift 型別。因此請使用uppercamelcase這種方式來命名(如someclass和somestructure等),以便符合標準 swift 型別的大寫命名風格(如string,int和bool)。相反的,請使用lowercamelcase這種方式為屬性和方法命名(如framerate和incrementcount),以便和型別名區分。

以下是定義結構體和定義類的示例:

struct resolution 

class videomode

生成結構體和類例項的語法非常相似:

let someresolution = resolution()

let somevideomode = videomode()

結構體和類都使用構造器語法來生成新的例項。構造器語法的最簡單形式是在結構體或者類的型別名稱後跟隨一對空括號,如resolution()或videomode()。通過這種方式所建立的類或者結構體例項,其屬性均會被初始化為預設值

通過使用點語法,訪問例項的屬性.

print("the width of someresolution is \(someresolution.width)")

// 列印 "the width of someresolution is 0"

可以訪問子屬性

print("the width of somevideomode is \(somevideomode.resolution.width)")

// 列印 "the width of somevideomode is 0"

可以使用點語法為變數屬性賦值

somevideomode.resolution.width = 1280

print("the width of somevideomode is now \(somevideomode.resolution.width)")

// 列印 "the width of somevideomode is now 1280"

所有結構體都有乙個自動生成的成員逐一構造器,用於初始化新結構體例項中成員的屬性。新例項中各個屬性的初始值可以通過屬性的名稱傳遞到成員逐一構造器之中:

let vga = resolution(width:640, height: 480)
與結構體不同,類例項沒有預設的成員逐一構造器

值型別被賦予給乙個變數、常量或者被傳遞給乙個函式的時候,其值會被拷貝。

實際上,在swift中,所有的基本型別:整數(integer)、浮點數(floating-point)、布林值(boolean)、字串(string)、陣列(array)和字典(dictionary),都是值型別,並且在底層都是以結構體的形式所實現。

swift中,所有的結構體和列舉型別都是值型別。這意味著它們的例項,以及例項中所包含的任何值型別屬性,在**中傳遞的時候都會被複製

與值型別不同,引用型別在被賦予到乙個變數、常量或者被傳遞到乙個函式時,其值不會被拷貝。因此,引用的是已存在的例項本身而不是其拷貝。

因為類是引用型別,有可能有多個常量和變數在幕後同時引用同乙個類例項。(對於結構體和列舉來說,這並不成立。因為它們作為值型別,在被賦予到常量、變數或者傳遞到函式時,其值總是會被拷貝。)

如果能夠判定兩個常量或者變數是否引用同乙個類例項將會很有幫助。為了達到這個目的,swift 內建了兩個恒等運算子:

運用這兩個運算子檢測兩個常量或者變數是否引用同乙個例項

if teneighty === alsoteneighty 

//列印 "teneighty and alsoteneighty refer to the same resolution instance."

請注意,「等價於」(用三個等號表示,=)與「等於」(用兩個等號表示,)的不同:

cc++或者objective-c語言使用指標來引用記憶體中的位址。乙個引用某個引用型別例項的swift常量或者變數,與c語言中的指標類似,但是並不直接指向某個記憶體位址,也不要求你使用星號(*)來表明你在建立乙個引用。swift 中的這些引用與其它的常量或變數的定義方式相同。

結構體例項總是通過值傳遞,類例項總是通過引用傳遞。這意味兩者適用不同的任務。當你在考慮乙個工程專案的資料結構和功能的時候,你需要決定每個資料結構是定義成類還是結構體。

按照通用的準則,當符合一條或多條以下條件時,請考慮構建結構體:

舉例來說,以下情境中適合使用結構體:

在所有其它案例中,定義乙個類,生成乙個它的例項,並通過引用來管理和傳遞。實際中,這意味著絕大部分的自定義資料構造都應該是類,而非結構體。

swift中,所以基本型別,諸如string,array和dictionary型別均以結構體的形式實現。這意味著被賦值給新的常量或變數,或者被傳入函式或方法中時,它們的值會被拷貝。

objective-c中nsstring,nsarray和nsdictionary型別均以的形式實現,而並非結構體。它們在被賦值或者被傳入函式或方法時,不會發生值拷貝,而是傳遞現有例項的引用。

注意以上是對字串、陣列、字典的「拷貝」行為的描述。在你的**中,拷貝行為看起來似乎總會發生。然而,swift 在幕後只在絕對必要時才執行實際的拷貝。swift 管理所有的值拷貝以確保效能最優化,所以你沒必要去迴避賦值來保證效能最優化。

參考:

php中的class和字元運算str

物件是儲存資料和有關如何處理資料的資訊的資料型別。在 php 中,必須明確地宣告物件。然後我們在物件類中定義資料型別,然後在該類的例項中使用此資料型別 class car function what color function print vars obj instantiate one obje...

Swift中 Class和Struct的區別

1.記憶體管理方式不一樣,類引用型別,分配在堆上。結構體值型別,分配在棧上。2.類,有析構。結構體不能有析構,playground中測試直接卡死。3.結構體建構函式,會自動生成帶引數的構造器。類不會對有初始化賦值的屬性,生成帶引數的構造器。2.類有繼承特性,結構體沒有繼承特性,自然也不存在對成員屬性...

Swift中的Class物件資源釋放

swift4 中對class的引用即為引用中,必須把所有的引用全部釋放才會完全釋放 如下例子中,reference1 初始化的person物件,然後將reference1賦值給reference2,reference3。此時三個宣告物件引用同乙個person的記憶體位址及資料,當釋放referenc...