来自苹果书的内容:
结构体和类之间最重要的区别之一是,在代码中传递结构体时,它们总是被复制,但是在传递类时则是按引用传递。
有人可以帮我理解这是什么意思吗?对我来说,类和结构体似乎是一样的。
来自苹果书的内容:
结构体和类之间最重要的区别之一是,在代码中传递结构体时,它们总是被复制,但是在传递类时则是按引用传递。
有人可以帮我理解这是什么意思吗?对我来说,类和结构体似乎是一样的。
这是一个带有 class
的示例。请注意,当名称更改时,两个变量引用的实例都会更新。Bob
现在已经变成了Sue
,无论何时引用Bob
,都将变为Sue
。
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"
现在,通过 struct
我们可以看到值被复制了,每个变量都保留了自己的一组值。 当我们将名称设置为 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"
所以,对于表示有状态的复杂实体,class
非常棒。但是对于仅仅是度量或相关数据位的值,则更适合使用struct
,这样您可以轻松地复制它们并进行计算或修改值,而不必担心副作用。
aStruct
和bStruct
具有相同的值。它们都有一个名为“Bob”的单一字段。但它们是两个不同的结构体。这在下一行得到证明,当您更改其中一个结构体的名称时,另一个结构体保持不变。 - Alex Wayne类和结构都可以:
只有类能够:
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
类是引用类型。这意味着,如果您将类的实例分配给变量,则它将仅保存实例的引用而不是副本。
命名类型
或名义类型
或带名称的类型
复合类型
或非名义类型
或无名称的类型
值类型
是指其值在分配给变量或常量、传递给函数或从函数返回时被复制的类型。(同时,as
和is
检查会复制结构体)
引用类型
在分配给变量或常量或传递给函数时不会被复制。
值类型:
结构体
,枚举
[关于],元组
struct String
,struct Array
(Set
,Dictionary
)
(Objective-C 中的 int
...)
字符串和内置集合类型是值类型,它们包含对 heap
的内部引用以管理其大小
引用类型:
Class
, Function
(Objective-C除外)
使用ARC
引用类型
时,会创建对原始实例的新引用(实例的地址被复制)。值类型
是默认推荐使用的。 值类型
最大的优点通常是它们是线程安全的
。
引用类型
优点:
deinit()
方法,===
,值类型
是在Swift中引入的,所以可以与Objective-C
互操作。以上的答案是正确的,我希望我的回答能够帮助那些不理解上面的答案的人。
在Swift中,有两种类型的对象:
它们之间的主要区别是:
例如,以下代码可以更好地理解这个概念。
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
这是它们的主要区别,但我们还有一些次要区别。
类
结构体
这个问题似乎是重复的,但以下内容可以回答大部分用例:
结构体(Structures)和类(Classes)之间最重要的区别之一是:结构体是值类型(Value types),在代码中传递时总是复制它们自己,而类是引用类型(Reference type),在传递时会通过引用传递。
此外,类具有继承(Inheritance),允许一个类继承另一个类的特征。
结构体属性存储在栈(Stack)上,而类实例存储在堆(Heap)上,因此,有时栈比类快得多。
结构体自动获得默认初始化程序,而在类中,我们必须进行初始化。
结构体在线程安全或单例的任何时候都是安全的。
并且也需要了解值类型和引用类型的区别,才能总结结构体和类之间的差异。
// sampleplayground.playground
class MyClass {
var myName: String
init(myName: String){
self.myName = myName;
}
}
var myClassExistingName = MyClass(myName: "DILIP")
var myClassNewName = myClassExistingName
myClassNewName.myName = "John"
print("Current Name: ",myClassExistingName.myName)
print("Modified Name", myClassNewName.myName)
print("*************************")
struct myStruct {
var programmeType: String
init(programmeType: String){
self.programmeType = programmeType
}
}
var myStructExistingValue = myStruct(programmeType: "Animation")
var myStructNewValue = myStructExistingValue
myStructNewValue.programmeType = "Thriller"
print("myStructExistingValue: ", myStructExistingValue.programmeType)
print("myStructNewValue: ", myStructNewValue.programmeType)
输出:
Current Name: John
Modified Name John
*************************
myStructExistingValue: Animation
myStructNewValue: Thriller
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"
struct A {
let a: Int
let c: Bool
}
在函数父对象或结构中本地存储的内存中,它会是类似这样的:
64bit for int
8 bytes for bool
now for
class A {
let a: Int
let c: Bool
}
与数据内容存储在本地内存、结构体或类不同,它将是一个单一指针。
64bit address of class A instance
当你复制这两个内容时,很容易看出它们之间的区别。如果复制第一个内容,你会复制int类型的64位和bool类型的8位;如果复制第二个内容,你会复制类A实例的64位地址,你可以有多个相同内存地址的副本,都指向同一个实例,但每个结构体的副本都是独立的。
现在情况可能变得复杂,因为你可以将两者混合使用,例如:
struct A {
let a: ClassA
let c: Bool
}
64bit address of class A instance
8 bytes for bool
对于一些苹果结构类型,情况变得更加复杂,因为它们实际上包含对象类型。关于引用数据的好处是,它可以存储在内存中,并且可以根据需要加长和缩短,它们可以非常大,不像存储在本地堆栈上的数据。因此,像String、Array、Set、Dictionary这样的类型虽然表现得像结构体,甚至在尝试修改它们时会制作内部数据的副本,以便您不改变所有出现的情况,但它们的数据仍然必须进行引用计数,因此包含大量这些类型的结构体仍然可能很慢,因为每个类型的内部数据都必须保留。
当然,传递结构类型可以减少许多错误的可能性,但根据它们包含的类型,它们也可能会减慢程序速度。
void my_func(int a)
和void my_func(int &a)
。这是编程中非常基础的问题。了解更多信息,请访问:https://dev59.com/s3RC5IYBdhLWcg3wOOP1 - superarts.org