为什么Swift中的字符串,数组和字典更改为值类型

时间:2022-12-21 04:16:35

In Objc string, array and dictionary are all reference types, while in Swift they are all value types.

在Objc字符串中,数组和字典都是引用类型,而在Swift中它们都是值类型。

  1. I want to figure out what's the reason behind the scenes, for my understanding, no matter it is a reference type or value type, the objects live in the heap in both Objc and Swift.

    我想弄清楚幕后的原因是什么,因为我的理解是,无论是引用类型还是值类型,对象都存在于Objc和Swift的堆中。

  2. Was the change for making coding easier? i.e. if it is reference type then the pointer to the object might not be nil, so need to check both pointer and the object not nil for accessing the object. While if it is value type then only need to check the object itself?

    编码的变化是否更容易?即如果它是引用类型,那么指向对象的指针可能不是nil,因此需要检查指针和对象不是nil以访问对象。如果它是值类型,那么只需要检查对象本身?

  3. But in terms of memory allocation, value types and reference types are same, right? both allocated same size of memory?

    但就内存分配而言,值类型和引用类型是一样的,对吧?两者分配相同大小的内存?

thanks

谢谢

4 个解决方案

#1


15  

Arrays, dictionaries etc. in Objective-C are often mutable. That means when I pass an array to another method, and then that array is modified behind the back of the other method, surprising (to put it gently) behaviour will happen.

Objective-C中的数组,字典等通常是可变的。这意味着当我将一个数组传递给另一个方法,然后在另一个方法的后面修改该数组时,会发生令人惊讶的(轻轻地说)。

By making arrays, dictionaries etc. value types, this surprising behaviour is avoided. When you receive a Swift array, you know that nobody is going to modify it behind your back. Objects that can be modified behind your back are a major source for problems.

通过制作数组,字典等值类型,可以避免这种令人惊讶的行为。当你收到一个Swift阵列时,你知道没有人会在你背后修改它。可以在背后修改的对象是问题的主要来源。

In reality, the Swift compiler tries to avoid unnecessary copying whenever possible. So even if it says that an array is officially copied, it doesn't mean that it is really copied.

实际上,Swift编译器会尽可能避免不必要的复制。因此,即使它表示数组被正式复制,也不意味着它真的被复制了。

#2


6  

The Swift team is very active on the official developer forums. So, I'm assuming that since you didn't ask there, you're more curious about the community's broader "sense" of what the change means, as opposed to the technical implementation details. If you want to understand exactly "why", just go ask them :)

Swift团队在官方开发者论坛上非常活跃。所以,我假设你没有在那里问过,你对社区对变革意味着什么的更广泛的“感觉”更加好奇,而不是技术实施细节。如果你想完全理解“为什么”,那就去问问他们:)

The explanation that makes the most sense to me is that Objects should be responsible for reacting to, and updating the state of your application. Values should be the state of your application. In other words, an Array or a String or a Dictionary (and other value types) should never be responsible for responding to user input or network input or error conditions, etc. The Objects handle that and store the resulting data into those values.

对我来说最有意义的解释是,Objects应负责对应用程序做出反应并更新其状态。值应该是您的应用程序的状态。换句话说,数组或字符串或字典(以及其他值类型)永远不应负责响应用户输入或网络输入或错误条件等。对象处理该数据并将结果数据存储到这些值中。

One cool feature in Swift, which makes a complex Value Type (like a Dictionary or a custom type like Person, as opposed to a simple Float) more viable, is that the value types can encapsulate rules and logic because they can have functions. If I write a value type Person as a struct, then the Person struct can have a function for updating a name due to marriage, etc. That's solely concerned with the data, and not with /managing/ the state. The Objects will still decide WHEN and WHY to updating a Person's name, but the business logic of how to go about doing so safely/test-ably can be included in the Value Type itself. Hence giving you a nice way to increase isolation and reduce complexity.

Swift中的一个很酷的特性是,它使一个复杂的Value Type(比如Dictionary或者像Person这样的自定义类型,而不是简单的Float)更可行,因为值类型可以封装规则和逻辑,因为它们可以具有函数。如果我将值类型Person写为结构,那么Person结构可以有一个函数来更新由于结婚等名称。这只关注数据,而不是/管理/状态。对象仍将决定更新人名的时间和原因,但是如何安全/可测试地执行此操作的业务逻辑可以包含在值类型本身中。因此,为您提供增加隔离度和降低复杂性的好方法。

#3


2  

In addition to the previous answers, there are also multi-threading issues to consider with sharing a Reference-Based collection type that we don't have to worry as much with sharing an instance of a type that is Value-Based and has Copy-On-Write behavior. Multi-core is becoming more and more proliferant even on iOS devices, so it has become more of an issue for the Swift language developers to consider.

除了之前的答案之外,还有一些多线程问题需要考虑共享基于参考的集合类型,我们不必担心共享基于价值的类型的实例并具有复制 - 写入行为。即使在iOS设备上,多核也正在变得越来越多,因此对于Swift语言开发人员来说,它已经成为一个问题。

#4


-4  

I do not know, whether this is the real idea behind it, but have a historical view on it:

我不知道,这背后是否是真正的想法,但有一个历史观点:

At the beginning, an array copy behaved by reference, when you changed an item in it. It behaved by value, when you changed the length of the array. They did it for performance reasons (less array copy). But of course this was, eh, how can I express that politly, eh, difficult with Swift at all, eh, let's call it a "do not care about a good structure if you can win some performance, you probably never need" approach. Some called that copy-on-write, what is not much more intelligent, because COW is transparent, while that behavior was not transparent. Typical Swift wording: Use a buzzword, use it the way, it fits to Swift, don't care about correctness.

在开头,当您更改其中的项目时,数组副本通过引用来表现。当您更改数组的长度时,它按值表现。他们出于性能原因(较少的阵列副本)来完成它。但当然这是,呃,我怎么能用Swift来表达政治上的,呃,困难,呃,我们称之为“如果你能赢得一些表现,就不要关心一个好的结构,你可能永远不需要”的方法。有些人称之为写时复制,更不聪明,因为COW是透明的,而这种行为并不透明。典型的Swift措辞:使用流行语,使用它的方式,它适合Swift,不关心正确性。

Later on arrays got a complete by copy behavior, what is less confusing. (You remember, Swift was for readability. Obviously in Swift's concept, readability means "less characters to read", but does not mean "better understandable". Typical Swift wording: Use a buzzword, use it the way, it fits to Swift, don't care about correctness. Did I already mention that?)

后来数组得到了一个完整的复制行为,更不容易混淆。 (你记得,Swift是为了可读性。显然,在Swift的概念中,可读性意味着“阅读的字符越来越少”,但并不意味着“更容易理解”。典型的Swift措辞:使用流行语,使用它的方式,它适合Swift,不关心正确性。我已经提到了吗?)

So, I guess it is still performance plus understandable behavior probably leading to less performance. (You will better know when a copy is needed in your code and you can still do that and you get a 0-operation from Cocoa, if the source array is immutable.) Of course, they could say: "Okay, by value was a mistake, we changed that." But they will never say.

所以,我猜这仍然是性能加上可理解的行为可能导致性能降低。 (您最好知道代码中何时需要副本,如果源数组是不可变的,您仍然可以从Cocoa获得0操作。)当然,他们可以说:“好的,按值来说一个错误,我们改变了。“但他们永远不会说。

However, now arrays in Swift behave consistently. A big progress in Swift! Maybe you can call it a programming language one sunny day.

但是,现在Swift中的数组表现一致。 Swift的一大进步!也许你可以在晴天称它为编程语言。

#1


15  

Arrays, dictionaries etc. in Objective-C are often mutable. That means when I pass an array to another method, and then that array is modified behind the back of the other method, surprising (to put it gently) behaviour will happen.

Objective-C中的数组,字典等通常是可变的。这意味着当我将一个数组传递给另一个方法,然后在另一个方法的后面修改该数组时,会发生令人惊讶的(轻轻地说)。

By making arrays, dictionaries etc. value types, this surprising behaviour is avoided. When you receive a Swift array, you know that nobody is going to modify it behind your back. Objects that can be modified behind your back are a major source for problems.

通过制作数组,字典等值类型,可以避免这种令人惊讶的行为。当你收到一个Swift阵列时,你知道没有人会在你背后修改它。可以在背后修改的对象是问题的主要来源。

In reality, the Swift compiler tries to avoid unnecessary copying whenever possible. So even if it says that an array is officially copied, it doesn't mean that it is really copied.

实际上,Swift编译器会尽可能避免不必要的复制。因此,即使它表示数组被正式复制,也不意味着它真的被复制了。

#2


6  

The Swift team is very active on the official developer forums. So, I'm assuming that since you didn't ask there, you're more curious about the community's broader "sense" of what the change means, as opposed to the technical implementation details. If you want to understand exactly "why", just go ask them :)

Swift团队在官方开发者论坛上非常活跃。所以,我假设你没有在那里问过,你对社区对变革意味着什么的更广泛的“感觉”更加好奇,而不是技术实施细节。如果你想完全理解“为什么”,那就去问问他们:)

The explanation that makes the most sense to me is that Objects should be responsible for reacting to, and updating the state of your application. Values should be the state of your application. In other words, an Array or a String or a Dictionary (and other value types) should never be responsible for responding to user input or network input or error conditions, etc. The Objects handle that and store the resulting data into those values.

对我来说最有意义的解释是,Objects应负责对应用程序做出反应并更新其状态。值应该是您的应用程序的状态。换句话说,数组或字符串或字典(以及其他值类型)永远不应负责响应用户输入或网络输入或错误条件等。对象处理该数据并将结果数据存储到这些值中。

One cool feature in Swift, which makes a complex Value Type (like a Dictionary or a custom type like Person, as opposed to a simple Float) more viable, is that the value types can encapsulate rules and logic because they can have functions. If I write a value type Person as a struct, then the Person struct can have a function for updating a name due to marriage, etc. That's solely concerned with the data, and not with /managing/ the state. The Objects will still decide WHEN and WHY to updating a Person's name, but the business logic of how to go about doing so safely/test-ably can be included in the Value Type itself. Hence giving you a nice way to increase isolation and reduce complexity.

Swift中的一个很酷的特性是,它使一个复杂的Value Type(比如Dictionary或者像Person这样的自定义类型,而不是简单的Float)更可行,因为值类型可以封装规则和逻辑,因为它们可以具有函数。如果我将值类型Person写为结构,那么Person结构可以有一个函数来更新由于结婚等名称。这只关注数据,而不是/管理/状态。对象仍将决定更新人名的时间和原因,但是如何安全/可测试地执行此操作的业务逻辑可以包含在值类型本身中。因此,为您提供增加隔离度和降低复杂性的好方法。

#3


2  

In addition to the previous answers, there are also multi-threading issues to consider with sharing a Reference-Based collection type that we don't have to worry as much with sharing an instance of a type that is Value-Based and has Copy-On-Write behavior. Multi-core is becoming more and more proliferant even on iOS devices, so it has become more of an issue for the Swift language developers to consider.

除了之前的答案之外,还有一些多线程问题需要考虑共享基于参考的集合类型,我们不必担心共享基于价值的类型的实例并具有复制 - 写入行为。即使在iOS设备上,多核也正在变得越来越多,因此对于Swift语言开发人员来说,它已经成为一个问题。

#4


-4  

I do not know, whether this is the real idea behind it, but have a historical view on it:

我不知道,这背后是否是真正的想法,但有一个历史观点:

At the beginning, an array copy behaved by reference, when you changed an item in it. It behaved by value, when you changed the length of the array. They did it for performance reasons (less array copy). But of course this was, eh, how can I express that politly, eh, difficult with Swift at all, eh, let's call it a "do not care about a good structure if you can win some performance, you probably never need" approach. Some called that copy-on-write, what is not much more intelligent, because COW is transparent, while that behavior was not transparent. Typical Swift wording: Use a buzzword, use it the way, it fits to Swift, don't care about correctness.

在开头,当您更改其中的项目时,数组副本通过引用来表现。当您更改数组的长度时,它按值表现。他们出于性能原因(较少的阵列副本)来完成它。但当然这是,呃,我怎么能用Swift来表达政治上的,呃,困难,呃,我们称之为“如果你能赢得一些表现,就不要关心一个好的结构,你可能永远不需要”的方法。有些人称之为写时复制,更不聪明,因为COW是透明的,而这种行为并不透明。典型的Swift措辞:使用流行语,使用它的方式,它适合Swift,不关心正确性。

Later on arrays got a complete by copy behavior, what is less confusing. (You remember, Swift was for readability. Obviously in Swift's concept, readability means "less characters to read", but does not mean "better understandable". Typical Swift wording: Use a buzzword, use it the way, it fits to Swift, don't care about correctness. Did I already mention that?)

后来数组得到了一个完整的复制行为,更不容易混淆。 (你记得,Swift是为了可读性。显然,在Swift的概念中,可读性意味着“阅读的字符越来越少”,但并不意味着“更容易理解”。典型的Swift措辞:使用流行语,使用它的方式,它适合Swift,不关心正确性。我已经提到了吗?)

So, I guess it is still performance plus understandable behavior probably leading to less performance. (You will better know when a copy is needed in your code and you can still do that and you get a 0-operation from Cocoa, if the source array is immutable.) Of course, they could say: "Okay, by value was a mistake, we changed that." But they will never say.

所以,我猜这仍然是性能加上可理解的行为可能导致性能降低。 (您最好知道代码中何时需要副本,如果源数组是不可变的,您仍然可以从Cocoa获得0操作。)当然,他们可以说:“好的,按值来说一个错误,我们改变了。“但他们永远不会说。

However, now arrays in Swift behave consistently. A big progress in Swift! Maybe you can call it a programming language one sunny day.

但是,现在Swift中的数组表现一致。 Swift的一大进步!也许你可以在晴天称它为编程语言。