摘自苹果书籍 “结构和类之间最重要的区别之一是,结构在代码中传递时总是被复制,但类是通过引用传递的。”
有人能帮我理解一下这是什么意思吗?对我来说,类和结构似乎是一样的。
摘自苹果书籍 “结构和类之间最重要的区别之一是,结构在代码中传递时总是被复制,但类是通过引用传递的。”
有人能帮我理解一下这是什么意思吗?对我来说,类和结构似乎是一样的。
当前回答
斯威夫特类型
命名类型或标称类型或有名称的类型 复合类型或非名义类型或没有名称的类型
值类型是一种类型,其值在赋值给变量或常量、传递给函数或从函数返回时被复制。(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结构]
在结构和类之间选择 类型 类和结构
其他回答
为了理解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建议使用更多的值类型,你可以看出他们的库是基于结构的,以避免引用类型带来的问题,比如无意中修改一个值等。结构是斯威夫特的发展方向。 希望能有所帮助。
下面是一个类的例子。请注意,当名称更改时,两个变量引用的实例将如何更新。鲍勃现在是苏了,所有提到鲍勃的地方都是这样。
class SomeClass {
var name: String
init(name: String) {
self.name = name
}
}
var aClass = SomeClass(name: "Bob")
var bClass = aClass // aClass and bClass now reference the same instance!
bClass.name = "Sue"
println(aClass.name) // "Sue"
println(bClass.name) // "Sue"
现在使用结构体,我们看到值被复制,每个变量保留自己的值集。当我们将名称设置为Sue时,aStruct中的Bob结构体不会被更改。
struct SomeStruct {
var name: String
init(name: String) {
self.name = name
}
}
var aStruct = SomeStruct(name: "Bob")
var bStruct = aStruct // aStruct and bStruct are two structs with the same value!
bStruct.name = "Sue"
println(aStruct.name) // "Bob"
println(bStruct.name) // "Sue"
所以对于表示有状态的复杂实体来说,类是非常棒的。但是对于仅仅是测量值或相关数据位的值,结构体更有意义,这样您可以轻松地复制它们并使用它们计算或修改值,而不用担心副作用。
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"
Struct是值类型。这意味着,如果你将结构的实例复制到另一个变量,它只是复制到变量。
值类型示例
struct Resolution {
var width = 2
var height = 3
}
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd //assigning struct instance to variable
println("Width of cinema instance is \(cinema.width)")//result is 1920
println("Width of hd instance is \(hd.width)")//result is 1920
cinema.width = 2048
println("Width of cinema instance is \(cinema.width)")//result is 2048
println("Width of hd instance is \(hd.width)")//result is 1920
类是引用类型。这意味着如果将类的一个实例赋值给一个变量,它将只保存对该实例的引用,而不是副本。
如果你仔细看苹果手册,你会看到这部分: 结构和枚举是值类型
在本节中,你会看到:
“let hd = Resolution(width: 1920, height: 1080) var cinema = hd This example declares a constant called hd and sets it to a Resolution instance initialized with the width and height of full HD video (1920 pixels wide by 1080 pixels high). It then declares a variable called cinema and sets it to the current value of hd. Because Resolution is a structure, a copy of the existing instance is made, and this new copy is assigned to cinema. Even though hd and cinema now have the same width and height, they are two completely different instances behind the scenes. Next, the width property of cinema is amended to be the width of the slightly-wider 2K standard used for digital cinema projection (2048 pixels wide and 1080 pixels high): cinema.width = 2048 Checking the width property of cinema shows that it has indeed changed to be 2048: println("cinema is now (cinema.width) pixels wide") // prints "cinema is now 2048 pixels wide However, the width property of the original hd instance still has the old value of 1920: println("hd is still (hd.width) pixels wide") // prints "hd is still 1920 pixels wide” When cinema was given the current value of hd, the values stored in hd were copied into the new cinema instance. The end result is two completely separate instances, which just happened to contain the same numeric values. Because they are separate instances, setting the width of cinema to 2048 doesn’t affect the width stored in hd.” Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l
这是结构体和类之间最大的区别。复制结构,引用类。