摘自苹果书籍 “结构和类之间最重要的区别之一是,结构在代码中传递时总是被复制,但类是通过引用传递的。”

有人能帮我理解一下这是什么意思吗?对我来说,类和结构似乎是一样的。


当前回答

已经有很多关于这方面的文章了,我想在这里加一个类比。希望你看完这篇文章后,心中永远不会再有疑虑: 底线: 类通过引用传递,而结构通过值传递。

假设你和你的朋友共享一个谷歌文档表。现在,如果他改变了其中的任何内容,你也会在谷歌文档上看到变化,这意味着你的副本也受到了影响。 这基本上是“通过引用传递”。

但假设,如果你有一个。xls文件保存在你的机器。你把那份文件交给你的朋友。现在,如果他在那个文件中做了任何更改,你的文件也不会被打乱/影响,因为你有自己的副本。 这基本上就是“按值传递”。 你有多个简单的程序已经在那里检查这个类比在快速操场。

其他回答

以上答案都是正确的,我希望我的回答能帮助到那些不理解以上答案的人。

在Swift中有两种类型的对象

结构体 类

它们之间的主要区别是

Struct是值类型 类是引用类型

例如这里的代码要理解得很好。

struct SomeStruct {
var a : Int;

init(_ a : Int) {
    self.a = a
}
}

class SomeClass {
var a: Int;

init(_ a: Int) {
    self.a = a
}

}
var x = 11

var someStruct1 = SomeStruct(x)
var someClass1 = SomeClass(x)

var someStruct2 = someStruct1
var someClass2 = someClass1

someClass1.a = 12
someClass2.a // answer is 12 because it is referencing to class 1     property a

someStruct1.a = 14
someStruct2.a // answer is 11 because it is just copying it not referencing it

这是主要的区别,但我们也有次要的区别。

必须声明初始化式(构造函数) 有deinitialisers 可以从其他类继承吗

结构体

它为你提供了自由初始化器,你不必声明初始化器,如果你声明了自由初始化器,它将被你声明的初始化器覆盖 没有去初始化 不能从其他结构继承

下面是一个例子,它精确地显示了struct和class之间的区别。

在操场上写的代码的截图

struct Radio1{
    var name:String
    //    init(name:String) {
    //        self.name = name
    //    }
}

struct Car1{
    var radio:Radio1?
    var model:String

}

var i1 = Car1(radio: Radio1(name:"murphy"),model:"sedan")
var i2 = i1
//since car instance i1 is a struct and 
//this car has every member as struct ,
//all values are copied into i2

i2.radio?.name //murphy
i2.radio = Radio1(name: "alpha")
i2.radio?.name //alpha

i1.radio?.name //murphy

//since Radio1 was struct , 
//values were copied and thus
// changing name  of instance of Radio1 in i2 
//did not bring change in i1

class Radio2{
    var name:String
    init(name:String) {
        self.name = name
    }
}

struct Car2{
    var radio:Radio2?
    var model:String

}
var i3 = Car2(radio: Radio2(name:"murphy"),model:"sedan")
//var radioInstance = Radio2(name: "murphy")
//var i3 = Car2(radio: radioInstance,model:"sedan")

var i4 = i3
//since i3 is instance of struct
//everything is copied to i4 including reference of instance of Radio2
//because Radio2 is a class



i4.radio?.name //murphy
i4.radio?.name="alpha"
i4.radio?.name //alpha

i3.radio?.name //alpha

//since Radio2 was class, 
//reference was copied and 
//thus changing name of instance 
//of Radio2 in i4 did  bring change in i3 too


//i4.radio?.name
//i4.radio = Radio2(name: "alpha")
//i4.radio?.name
//
//i3.radio?.name
1.structure is value type.
   = > when we assign structure variable to other variable or pass as parameter to function, it creates separate/new copy => so that changes made on one variable does not  reflect on another.[We can say like **call by value** concept] 
Example :

    struct DemoStruct 
    { 
        var value: String 
        init(inValue: String) 
        { 
            self.value = inValue 
        } 
    } 


var aStruct = DemoStruct(inValue: "original") 
var bStruct = aStruct // aStruct and bStruct are two structs with the same value! but references to diff location`enter code here`
bStruct.value = "modified" 

print(aStruct.value) // "original" 
print(bStruct.value) // "modified"


2.class is reference type.
 = > when we assign structure variable to other variable or pass as parameter to function, it **does not** creates separate/new copy => so that changes made on one variable does not  reflect on another.[We can say like **call by reference** concept] 
Example:
class DemoClass 
{   
    var value: String 
    init(inValue: String) 
    {
        self.value = inValue 
    } 
} 

var aClass = DemoClass(inName: "original") 
var bClass = aClass // aClass and bClass now reference the same instance! 
bClass.value = "modified" 

print(aClass.value) // "modified" 
print(bClass.value) // "modified"

斯威夫特类型

命名类型或标称类型或有名称的类型 复合类型或非名义类型或没有名称的类型

值类型是一种类型,其值在赋值给变量或常量、传递给函数或从函数返回时被复制。(as and is检查构造的副本)

当引用类型被赋值给变量或常量,或者被传递给函数时,引用类型不会被复制

值类型:

Struct, Enum[About],元组 struct String, struct Array(Set, Dictionary)

(objective - c int…)

字符串,内置集合值类型包含对堆的内部引用,以管理它的大小

当您分配或传递值类型时,将创建数据的新副本。copy on write - COW机制用于某些特定的类(如Collections(Array, Dictionary, Set))[About],并进行了一些优化,例如在修改对象时创建副本。对于自定义类型,您应该自己支持COW 当你修改一个实例时,它只在局部起作用。 如果Value为局部变量,则使用堆栈内存[关于]

引用类型: 类,函数

(Objective-C所有其他)

使用ARC

当你分配或传递引用类型时,一个新的引用将被创建到原始实例(实例的地址被复制)。 当您修改一个实例时,它会产生全局影响,因为该实例可以被指向它的任何引用共享和访问。 通常使用堆内存[大约]

建议默认为“type”。Value类型的最大优点是它们通常是线程安全的

参考类型

它们可以遗传, 可以使用Deinit (), 通过引用===比较实例, Objective-C互操作性,因为值类型是在Swift中引入的。

[堆栈vs堆] [let vs var, class vs struct] [类别vs结构]

在结构和类之间选择 类型 类和结构

已经有很多关于这方面的文章了,我想在这里加一个类比。希望你看完这篇文章后,心中永远不会再有疑虑: 底线: 类通过引用传递,而结构通过值传递。

假设你和你的朋友共享一个谷歌文档表。现在,如果他改变了其中的任何内容,你也会在谷歌文档上看到变化,这意味着你的副本也受到了影响。 这基本上是“通过引用传递”。

但假设,如果你有一个。xls文件保存在你的机器。你把那份文件交给你的朋友。现在,如果他在那个文件中做了任何更改,你的文件也不会被打乱/影响,因为你有自己的副本。 这基本上就是“按值传递”。 你有多个简单的程序已经在那里检查这个类比在快速操场。