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

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


当前回答

类和结构都可以做到:

定义属性来存储值 定义提供功能的方法 被扩展 遵守协议 定义初始化 定义下标以提供对其变量的访问

唯一的类可以做到:

继承 铸字 定义deinitialisers 允许多个引用进行引用计数。

其他回答

类和结构都可以做到:

定义属性来存储值 定义提供功能的方法 被扩展 遵守协议 定义初始化 定义下标以提供对其变量的访问

唯一的类可以做到:

继承 铸字 定义deinitialisers 允许多个引用进行引用计数。

为了理解struct和class之间的区别,我们需要知道值类型和引用类型之间的主要区别。struct是值类型,这意味着对它们的每一次更改都只会修改该值,类是引用类型,引用类型中的每一次更改都将修改分配在内存或引用位置的值。例如:

让我们从一个类开始,这个类符合Equatable只是为了能够比较实例,我们创建了一个名为pointclassinstancea的实例和另一个名为pointClassInstanceB的实例,我们将类a分配给类B,现在断言说它们是相同的…

class PointClass: Equatable {
    var x: Double
    var y: Double

    init(x: Double, y: Double) {
        self.x = x
        self.y = y
    }

    static func == (lhs: PointClass, rhs: PointClass) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}

var pointClassInstanceA = PointClass(x: 0, y: 0)
var pointClassInstanceB = pointClassInstanceA

assert(pointClassInstanceA==pointClassInstanceB) 

pointClassInstanceB.x = 10
print(pointClassInstanceA.x)
//this prints 10

好的,这里发生了什么为什么如果我们改变了pointclassinstanceb的x值它也改变了pointClassInstanceA的x值?这展示了引用类型是如何工作的,当我们将实例A赋值为实例B的值,然后我们修改其中一个的X,它会改变两个X,因为它们共享相同的引用,而改变的是该引用的值。

让我们用结构体做同样的事情

struct PointStruct: Equatable {
    var x: Double
    var y: Double

    init(x: Double, y: Double) {
        self.x = x
        self.y = y
    }

    static func == (lhs: PointStruct, rhs: PointStruct) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}
var pointStructInstanceA = PointStruct(x: 0, y: 0)
var pointStructInstanceB = pointStructInstanceA

assert(pointStructInstanceA==pointStructInstanceB)
pointStructInstanceB.x = 100
print(pointStructInstanceA.x)
//this will print 0

我们的结构与我们的类基本相同,但现在你可以看到,当你打印pointStructInstanceA的x值时,它没有改变,这是因为值类型的工作方式不同,它们的一个实例上的每一个变化都是“独立的”,不会影响到另一个实例。

Swift建议使用更多的值类型,你可以看出他们的库是基于结构的,以避免引用类型带来的问题,比如无意中修改一个值等。结构是斯威夫特的发展方向。 希望能有所帮助。

斯威夫特类型

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

值类型是一种类型,其值在赋值给变量或常量、传递给函数或从函数返回时被复制。(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结构]

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

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"

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

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

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