摘自苹果书籍 “结构和类之间最重要的区别之一是,结构在代码中传递时总是被复制,但类是通过引用传递的。”
有人能帮我理解一下这是什么意思吗?对我来说,类和结构似乎是一样的。
摘自苹果书籍 “结构和类之间最重要的区别之一是,结构在代码中传递时总是被复制,但类是通过引用传递的。”
有人能帮我理解一下这是什么意思吗?对我来说,类和结构似乎是一样的。
当前回答
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"
其他回答
下面是一个类的例子。请注意,当名称更改时,两个变量引用的实例将如何更新。鲍勃现在是苏了,所有提到鲍勃的地方都是这样。
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"
所以对于表示有状态的复杂实体来说,类是非常棒的。但是对于仅仅是测量值或相关数据位的值,结构体更有意义,这样您可以轻松地复制它们并使用它们计算或修改值,而不用担心副作用。
正如许多人已经指出复制结构体和类的区别一样,这可以从它们在c语言中的来源来理解,像这样的结构体
struct A {
let a: Int
let c: Bool
}
在func父对象或结构体的局部内存中,它将是这样的
64bit for int
8 bytes for bool
现在
class A {
let a: Int
let c: Bool
}
而不是存储在本地内存或结构或类中的数据内容,它将是一个单一指针
64bit address of class A instance
当你复制这两个时,很容易看出为什么会有区别,复制第一个,你复制了64位的int和8位的bool,复制第二个,你复制了64位的地址到A类的实例,你可以有同一个内存地址的多个副本,都指向同一个实例,但结构体的每个副本都将是它自己的副本。
现在事情变得复杂了因为你可以把这两个混合起来
struct A {
let a: ClassA
let c: Bool
}
你的记忆会是这样的
64bit address of class A instance
8 bytes for bool
This is a problem because even though you have multiple copies of the struct in your program, they all have a copy to the same object ClassA, this means just like multiples reference to instance ClassA you pass around have to have a reference count kept of how many reference to the object exists to know when to delete them, you program can have multiple references to struct A that need to keep a reference count to their ClassA instances, this can be time consuming if your struct has a lot of classes in them, or the structs it contains has lots of classes in them, now when you copy your struct, the compiler has to generate code that goes through every single class instance referenced in your struct and substructs, and increment there reference count to keep track of how many references there are. This can make classes much faster to pass around as you just need to copy its single address, and it won't need to increase the reference count of any of its children because it want reduce the reference count of any child it contains until its own reference count reaches 0.
The thing gets even more complicated with some Apple struct types, that they actually have object types in them, the good thing about data that is reference to, is it can be stored in memory and be lengthened and contractor at will and they can be very large, unlike data stored on local stack, so types like String, Array, Set, Dictionary though they act like struct and will even make a duplicate of there internal data if you try to modify them so you don't change all occurrence, there data still has to be reference counted and so a struct containing a lots of these types can still be slow, because the internal data for each one has to be retained.
当然,传递结构类型可以减少大量错误的可能性,但它们也会降低程序的速度,这取决于所包含的类型。
以上答案都是正确的,我希望我的回答能帮助到那些不理解以上答案的人。
在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 可以从其他类继承吗
结构体
它为你提供了自由初始化器,你不必声明初始化器,如果你声明了自由初始化器,它将被你声明的初始化器覆盖 没有去初始化 不能从其他结构继承
Usually (in most programming languages), objects are blocks of data that are stored on heap, and then a reference (normally a pointer) to these blocks, contains a name is using to access these blocks of data. This mechanism allows sharing objects in the heap by copying the value of their references (pointers). This is not the case of basic data types such as Integers, and that is because the memory needed to create a reference is almost the same as the object (in this case integer value). Thus, they will be passed as values not as a reference in the case of large objects.
Swift使用struct来提高String和Array对象的性能。
这是一本很好的读物
下面是一个例子,它精确地显示了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