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

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


当前回答

如果你仔细看苹果手册,你会看到这部分: 结构和枚举是值类型

在本节中,你会看到:

“​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

这是结构体和类之间最大的区别。复制结构,引用类。

其他回答

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

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

在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 可以从其他类继承吗

结构体

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

这个问题似乎是重复的,但无论如何,下面的问题将回答大多数用例:

One of the most important differences between structures and classes is that structures are value types and are always copied when they are passed around in your code, and classes are reference type and are passed by reference. Also, classes have Inheritance which allows one class to inherit the characteristics of another. Struct properties are stored on Stack and Class instances are stored on Heap hence, sometimes the stack is drastically faster than a class. Struct gets a default initializer automatically whereas in Class, we have to initialize. Struct is thread safe or singleton at any point of time.

而且, 要总结结构和类之间的区别,有必要了解值类型和引用类型之间的区别。

在复制值类型时,它将从其中复制所有数据 你要复制到新变量中的东西。它们是分开的 事物和改变一个并不影响另一个。 复制引用类型时,新变量引用 与你要复制的东西相同的内存位置。这意味着 改变一个会改变另一个因为它们都指向 相同的内存位置。 下面的示例代码可以作为参考。

/ / 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

如果你仔细看苹果手册,你会看到这部分: 结构和枚举是值类型

在本节中,你会看到:

“​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

这是结构体和类之间最大的区别。复制结构,引用类。

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"