In fact, when Swift 1.0 came out, I found that there was a serious error in its array variability design. Swift 2.0 fixed the problem, but their correction method was not misses, which led to other problems. This error has continued to this day. Swift 1.0 attempts to use the difference between Var and let to specify the variability of an array member, but in fact Var and let can only specify the variability of the array reference, not the variable of the array member. For example, the Swift 1.0 attempts to implement this semantics: var shoppinglist = ["Eggs", "Milk"]//can assign a value to an array member shoppinglist[0] = "Salad" Let shoppinglist = [ "Eggs", "Milk"]//cannot assign a value to an array member, error shoppinglist[0] = "Salad" This is wrong. In Swift 1.0, an array, like any other object, is a "reference type". To understand this problem, you should clearly distinguish between the array reference and the array member. In this example, Shoppinglist is an array reference, and Shoppinglist[0] is accessing an array member, which is very different. The Var and let is used to specify whether the Shoppinglist reference is mutable, which is to determine whether Shoppinglist can point to another array object. The correct usage should be this: var shoppinglist = ["Eggs", "Milk"]//can assign a value to the array reference = ["Shoppinglist", "salad" noodles can be assigned to an array member Value shoppinglist[0] = "Salad" Let shoppinglist = ["Eggs", "Milk"]//cannot assign a value to the array reference, error shoppinglist = ["Salad", "noodles "]//let cannot restrict assignment to an array member, no error shoppinglist[0] =" Salad "means you can use Var and allow to limit shoppinGList the variability of this reference and cannot be used to limit the variability of member accesses such as Shoppinglist[0]. Once used to specify the variability of array reference, VAR and let can no longer be used to specify the variability of array members. In fact, when Var and let are used for local variable definitions, only the variability of the data on the stack can be specified. If you understand that the reference is on a stack, and the array of Swift 1.0 is on the heap, you will understand that the array member (a heap of data) is denatured and must be specified in a different way, rather than using Var and let. Many ancient languages have seen this problem clearly, and they explicitly specify the variability of stacks and heap data in two different ways. C + + Programmers all know the difference between int const * and int * Const. Objective C Programmers all know the difference between Nsarray and Nsmutablearray. I don't know why the designers of Swift do not see the problem and try to use the same keywords (var and let) to specify the variability of the stack and heap data in two different locations. In fact, immutable and mutable arrays should be represented by two different types, like Objective C's Nsarray and Nsmutablearray, rather than using VAR and let to differentiate. Swift 2.0 fixes the problem, but unfortunately, it's a bug in its way. Swift 2.0 makes an outrageous change, which changes the array from reference type to the so-called value type, which means that the entire array is placed on the stack, not on the heap. This seems to solve the above problem, because the array becomes the value type, then Shoppinglist is not reference, but represents the entire array itself. So in the case where array is value type, you can actually use Var and let to determine if its members are mutable. Let shoppinglist = ["Eggs", "Milk"]//cannot assign a value to an array member because shoppinglist is value type//It represents an entire array instead of a pointer//any part of this array Immutable shoppinglist[0] = "Salad" It seems like a viable solution, but it doesn't hitThe key. This is a fits approach, which brings with it another problem. The array is used as the value type, so that each assignment or argument to the array variable must be copied. You can't have two variables pointing to the same array, which means that the array can no longer be shared. For example: var a = [1, 2, the contents of 3]//A are copied to b//A and B are two different arrays, have the same content var B = a This violates the programmer's mental model of the large structure of the array, they no longer have clear and convenient access to ARR Ay to think. Because the array will be inadvertently copied automatically, it is easy to make mistakes. An array copy takes a lot of time, and even if the recipient does not modify it, it has to be copied, so it has a significant effect on efficiency. Cannot share the same array, read and write data in it, is a great loss of functionality. For this reason, there is no other modern language (java,c#, ...). ) to use the array as the value type. If you look through the substance of value type, you will find that this whole concept exists, which is almost meaningless in modern languages with garbage collection (GC). Some new languages, such as Swift and Rust, try to use value type to address the efficiency of memory management, but the performance gains are negligible, and the headaches and hassles of programmers are obvious. Completely using the reference type language (such as Java,scheme,python), programmers do not need to think about the difference between the value type and the reference type, greatly simplifying and accelerating the programming thinking process. Java not only has a very efficient GC, but also can use escape analysis to automatically put some heap data on the stack, the programmer does not need to think to achieve the value of a little bit of the performance gains. By contrast, the value type of Swift,rust and C # makes more of a hassle than a real performance advantage. Swift 1.0 This is a mistake that I've seen at a glance, and you might find that the compiler expert is not equal to the program language expert. Many experienced programming language experts knew that it was wrong to see Swift's original array design. As long as there is a language expert in the team to point out this problem, there is no need for such repeated changes toss. Why did Swift not find this problem until the 1.0 release, and the 2.0 fix was still wrong? I guess that's because Apple didn't hire a qualifiedThe design of Swift, or qualified people, but their advice was not adopted by the leader. Swift's chief designer is Chris Lattner, the designer of LLVM. He is a good compiler expert, but in the programming language design, I am afraid that can only be considered amateur level. Compilers and programming languages, are really two very different areas. Apple's leaders think good compiler writers can design good programming languages so that Chris Lattner is the chief designer. The SWIFT team, unlike the Go language team, is completely smattering, and they do have a certain foundation in terms of language, so Swift does not generally have a particularly serious problem. However, it can be seen that these people skills are not deep enough, with the ego of young people, impetuous, blind innovation and reference to the spirit. Some designs do not come from their own insights, but simply "draw on" other languages, so it is possible to make mistakes that experienced language experts will never make. The first time you should do the right thing, but need to go through a lot of rework. So that each new version, there are some "incompatible changes", resulting in the old version of the language written out of the code can no longer be used. This trend will continue in Swift 3.0. Because of Apple's dominance, this may not be the end of the world for Swift, but it does make a big taboo in language design. A good language can be missing some features, but it should never add the wrong design, resulting in incompatible changes in the future. I hope Apple will soon recruit some of the most senior language design experts to adopt their suggestions. BTW, if Apple pays enough, I could consider working part-time as their language design consultant;-) Related videos: Swift 2.2 Basic Tutorial http://www.maiziedu.com/course/772/
What are the design errors for the Swift language?