日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Swift结构体与类

發布時間:2025/7/14 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Swift结构体与类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在面向過程的編程語言(如C語言)中,結構體用得比較多,但是面向對象之后,如在C++和Objective-C中,結構體已經很少使用了。這是因為結構體能夠做的事情,類完全可以取而代之。
而Swift語言卻非常重視結構體,把結構體作為實現面向對象的重要手段。Swift中的結構體與C++和Objective-C中的結構體有很大的差別,C++和Objective-C中的結構體只能定義一組相關的成員變量,而Swift中的結構體不僅可以定義成員變量(屬性),還可以定義成員方法。因此,我們可以把結構體看做是一種輕量級的類。
Swift中的類和結構體非常類似,都具有定義和使用屬性、方法、下標和構造器等面向對象特性,但是結構體不具有繼承性,也不具備運行時強制類型轉換、使用析構器和使用引用計等能力。
一、類和結構體定義
Swift中的類和結構體定義的語法也是非常相似的。我們可以使用class關鍵詞定義類,使用struct關鍵詞定義結構體,它們的語法格式如下:
class 類名 {
? ? 定義類的成員
}
struct 結構體名 {
? ? 定義結構體的成員
}
從語法格式上看,Swift中的類和結構體的定義更類似于Java語法,不需要像C++和Objective-C那樣把接口部分和實現部分放到不同的文件中。
類名、結構體名的命名規范與枚舉類型的要求是一樣的。下面我們來看一個示例:
class Employee { //定義員工類
? ? var no : Int = 0 //定義員工編號屬性
? ? var name : String = "" //定義員工姓名屬性
? ? var job : String? //定義工作屬性
? ? var salary : Double = 0 //定義薪資屬性


? ? var dept : Department?? //定義所在部門屬性
}


struct Department { //定義部門結構體
? ? var no : Int = 0 //定義部門編號屬性
? ? var name : String = "" //定義部門名稱屬性
}
Employee是我們定義的類,Department是我們定義的結構體。在Employee和Department中我們只定義了一些屬性。關于屬性的內容我們將在下一章介紹。
Employee和Department是有關聯關系的,Employee所在部門的屬性dept與Department關聯起來,它們的類圖如下圖所示。
?
我們可以通過下列語句實例化:
var emp = Employee()
var dept = Department()
Employee()和Department()是調用它們的構造器實現實例化,關于構造器我們會在14.1節介紹。
提示 實例化之后會開辟內存空間,emp和dept被稱為“實例”,但只有類實例化的“實例”才能被稱為“對象”。事實上,不僅僅是結構體和類可以實例化,枚舉、函數類型和閉包開辟內存空間的過程也可以稱為實例化,結果也可以叫“實例”,但不能叫“對象”。
二、再談值類型和引用類型
數據類型可以分為:值類型和引用類型,這是由賦值或參數傳遞方式決定的。值類型就是在賦值或給函數傳遞參數時候,創建一個副本,把副本傳遞過去,這樣在函數的調用過程中不會影響原始數據。引用類型就是在賦值或給函數傳遞參數的時候,把本身數據傳遞過去,這樣在函數的調用過程中會影響原始數據。
在眾多的數據類型中,我們只需記住:只有類是引用類型,其他類型全部是值類型。即便結構體與類非常相似,它也是值類型。值類型還包括整型、浮點型、布爾型、字符串、元組、集合和枚舉。
Swift中的引用類型與Java中的引用類型是一樣的,Java中的類也是引用類型。如果你沒有Java經驗,可以把引用類型理解為C、C++和Objective-C語言中的指針類型,只不過不需要在引用類型變量或常量前面加星號(*)。
下面我們看一個示例:

[html]?view plaincopy
  • var?dept?=?Department()?①??
  • dept.no?=?10??
  • dept.name?=?"Sales"?????????②??
  • ??
  • ??
  • var?emp?=?Employee()????????③??
  • emp.no?=?1000??
  • emp.name?=?"Martin"??
  • emp.job?=?"Salesman"??
  • emp.salary?=?1250??
  • emp.dept?=?dept?????????????④??
  • ??
  • ??
  • func?updateDept?(dept?:?Department)?{???⑤??
  • ????dept.name?=?"Research"??⑥??
  • }??
  • ??
  • ??
  • println("Department更新前:\(dept.name)")???⑦??
  • updateDept(dept)????????????????⑧??
  • println("Department更新后:\(dept.name)")???⑨??
  • ??
  • ??
  • func?updateEmp?(emp?:?Employee)?{???⑩??
  • ????emp.job?=?"Clerk"??????????
  • }??
  • ??
  • ??
  • println("Employee更新前:\(emp.job)")??????
  • updateEmp(emp)?????????????????
  • println("Employee更新后:\(emp.job)")??????


  • 上述代碼第①~②行創建Department結構體實例,并設置它的屬性。代碼第③~④行創建Employee類實例,并設置它的屬性。
    為了測試結構體是否是值類型,我們在第⑤行代碼定義了updateDept函數,它的參數是Department結構體實例。第⑥行代碼dept.name = "Research"是改變dept實例。然后在第⑦行打印更新前的部門名稱屬性,在第⑧行進行更新,在第⑨行打印更新后的部門名稱屬性。如果更新前和更新后的結果一致,則說明結構體是值類型,反之則為引用類型。事實上第⑥行代碼會有編譯錯誤,錯誤信息如下。
    Playground execution failed: error: <REPL>:34:15: error: cannot assign to 'name' in 'dept'
    ? ? dept.name = "Research"
    ? ? ~~~~~~~~~ ^
    這個錯誤提示dept.name = "Research"是不能賦值的,這說明了dept結構體不能修改,因為它是值類型。其實有另外一種辦法可以使值類型參數能夠以引用類型傳遞,我們在第9章介紹過使用inout聲明的輸入輸出類型參數,這里需要修改一下代碼:
    func updateDept (inout dept : Department) {
    ? ? dept.name = "Research"
    }


    println("Department更新前:\(dept.name)")
    updateDept(&dept)
    println("Department更新后:\(dept.name)")
    我們不僅要將參數聲明為inout,而且要在使用實例前加上&符號。這樣修改后輸出結果如下:
    Department更新前:Sales
    Department更新后:Research
    相比之下,第⑩行代碼是定義updateEmp函數,它的參數是Employee類的實例,我們不需要將參數聲明為inout類型。在第?行修改emp沒有編譯錯誤,這說明Employee類是引用類型,在調用的時候不用在變量前面添加&符號,見代碼第 行。輸出結果如下:
    Employee更新前:Salesman
    Employee更新后:Clerk
    這個結果再次說明了類是引用類。
    三、引用類型的比較
    我們在第4章介紹了基本運算符,提到了恒等于(===)和不恒等于(!===)關系運算符。===用于比較兩個引用是否為同一個實例,!===則恰恰相反,它只能用于引用類型,也就是類的實例。
    下面我們看一個示例:

    [html]?view plaincopy
  • var?emp1?=?Employee()???????①??
  • emp1.no?=?1000??
  • emp1.name?=?"Martin"??
  • emp1.job?=?"Salesman"??
  • emp1.salary?=?1250??
  • ??
  • ??
  • var?emp2?=?Employee()???????②??
  • emp2.no?=?1000??
  • emp2.name?=?"Martin"??
  • emp2.job?=?"Salesman"??
  • emp2.salary?=?1250??
  • ??
  • ??
  • ??
  • ??
  • if?emp1?===?emp2????????????????③??
  • {??
  • ????println("emp1?===?emp2")??
  • }??
  • if?emp1?===?emp1????????????????④??
  • {??
  • ????println("emp1?===?emp1")??
  • }??
  • ??
  • ??
  • var?dept1?=?Department()????⑤??
  • dept1.no?=?10??
  • dept1.name?=?"Sales"??
  • ??
  • ??
  • var?dept2?=?Department()????⑥??
  • dept2.no?=?10??
  • dept2.name?=?"Sales"??
  • ??
  • ??
  • if?dept1?==?dept2???//編譯失敗??⑦??
  • {??
  • ????println("dept1?===?dept2")??
  • }??


  • 上述代碼第①行和第②行分別創建了emp1和emp2兩個Employee實例。在代碼第③行比較emp1和emp2兩個引用是否為一個實例。可以看到,比較結果為False,也就是emp1和emp2兩個引用不是一個實例,即便是它們內容完全一樣,結果也是False,而第④行的比較結果為True。如果我們采用==比較,結果會如何呢?代碼如下:
    if emp1 == emp2?
    {
    ? ? println("emp1 === emp2")
    }
    答案是有如下編譯錯誤。==比較要求兩個實例的類型(類、結構體、枚舉等)必須要在該類型中重寫==運算符,定義相等規則。同樣的錯誤也會發生在第⑦行代碼。
    Playground execution failed: error: <REPL>:42:9: error: could not find an overload for '==' that accepts the supplied arguments
    if emp1 == emp2
    ? ?~~~~~^~~~~~~
    代碼第⑤行和第⑥行分別創建了dept1和dept2兩個Department實例。在代碼第⑦行使用==比較dept1和dept2兩個值是否相等,不僅不能比較,而且還會發生編譯錯誤,這在上面已經解釋過了。
    如果我們采用恒等于===比較dept1和dept2,結果會如何呢?代碼如下:
    if dept1 === dept2
    {
    ? ? println("dept1 === dept2")
    }

    我們發現會有編譯錯誤。===不能比較值類型,而Department結構體是值類型,因此不能使用===比較。

    ?

    ?

    ?

    ?

    更多內容請關注國內第一本Swift圖書《Swift開發指南》 本書交流討論網站:http://www.51work6.com/swift.php 歡迎加入Swift技術討論群:362298485

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    歡迎關注智捷iOS課堂微信公共平臺

    轉載于:https://www.cnblogs.com/iOS-Blog/p/3946812.html

    總結

    以上是生活随笔為你收集整理的Swift结构体与类的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。