The "++" and "--" operators have been deprecated Xcode 7.3
Solution 1
A full explanation here from Chris Lattner, Swift's creator. I'll summarize the points:
- It's another function you have to learn while learning Swift
- Not much shorter than
x += 1
- Swift is not C. Shouldn't carry them over just to please C programmers
- Its main use is in C-style for loop:
for i = 0; i < n; i++ { ... }
, which Swift has better alternatives, likefor i in 0..<n { ... }
(C-style for loop is going out as well) - Can be tricky to read and maintain, for eg, what's the value of
x - ++x
orfoo(++x, x++)
? - Chris Lattner doesn't like it.
For those interested (and to avoid link rot), Lattner's reasons in his own words are:
These operators increase the burden to learn Swift as a first programming language - or any other case where you don't already know these operators from a different language.
Their expressive advantage is minimal - x++ is not much shorter than x += 1.
Swift already deviates from C in that the =, += and other assignment-like operations returns Void (for a number of reasons). These operators are inconsistent with that model.
Swift has powerful features that eliminate many of the common reasons you'd use ++i in a C-style for loop in other languages, so these are relatively infrequently used in well-written Swift code. These features include the for-in loop, ranges, enumerate, map, etc.
Code that actually uses the result value of these operators is often confusing and subtle to a reader/maintainer of code. They encourage "overly tricky" code which may be cute, but difficult to understand.
While Swift has well defined order of evaluation, any code that depended on it (like foo(++a, a++)) would be undesirable even if it was well-defined.
These operators are applicable to relatively few types: integer and floating point scalars, and iterator-like concepts. They do not apply to complex numbers, matrices, etc.
Finally, these fail the metric of "if we didn't already have these, would we add them to Swift 3?"
Solution 2
I realize that this comment doesn't answer the question nevertheless there may be people looking for a solution how to keep these operators working and such a solution can be found in the bottom. 😇
I personally prefer ++
and --
operators. I can't agree with the opinion that they are tricky or hard to manage. Once the developer understand what these operators do (and we are talking about pretty simple stuff) the code should be very clear.
In the explanation why the operators were deprecated is mentioned that their main use was in C-style for loops. I don't know about others but I personally don't use C-style loops at all and there are still many other places or situations when ++
or --
operator is useful.
I would like to also mention that varName++
returns a value so it can be used in the return
whereas varName += 1
can not.
For any of you who would like to keep these operators working here is the solution:
prefix operator ++ {}
postfix operator ++ {}
prefix operator -- {}
postfix operator -- {}
// Increment
prefix func ++(inout x: Int) -> Int {
x += 1
return x
}
postfix func ++(inout x: Int) -> Int {
x += 1
return (x - 1)
}
prefix func ++(inout x: UInt) -> UInt {
x += 1
return x
}
postfix func ++(inout x: UInt) -> UInt {
x += 1
return (x - 1)
}
prefix func ++(inout x: Int8) -> Int8 {
x += 1
return x
}
postfix func ++(inout x: Int8) -> Int8 {
x += 1
return (x - 1)
}
prefix func ++(inout x: UInt8) -> UInt8 {
x += 1
return x
}
postfix func ++(inout x: UInt8) -> UInt8 {
x += 1
return (x - 1)
}
prefix func ++(inout x: Int16) -> Int16 {
x += 1
return x
}
postfix func ++(inout x: Int16) -> Int16 {
x += 1
return (x - 1)
}
prefix func ++(inout x: UInt16) -> UInt16 {
x += 1
return x
}
postfix func ++(inout x: UInt16) -> UInt16 {
x += 1
return (x - 1)
}
prefix func ++(inout x: Int32) -> Int32 {
x += 1
return x
}
postfix func ++(inout x: Int32) -> Int32 {
x += 1
return (x - 1)
}
prefix func ++(inout x: UInt32) -> UInt32 {
x += 1
return x
}
postfix func ++(inout x: UInt32) -> UInt32 {
x += 1
return (x - 1)
}
prefix func ++(inout x: Int64) -> Int64 {
x += 1
return x
}
postfix func ++(inout x: Int64) -> Int64 {
x += 1
return (x - 1)
}
prefix func ++(inout x: UInt64) -> UInt64 {
x += 1
return x
}
postfix func ++(inout x: UInt64) -> UInt64 {
x += 1
return (x - 1)
}
prefix func ++(inout x: Double) -> Double {
x += 1
return x
}
postfix func ++(inout x: Double) -> Double {
x += 1
return (x - 1)
}
prefix func ++(inout x: Float) -> Float {
x += 1
return x
}
postfix func ++(inout x: Float) -> Float {
x += 1
return (x - 1)
}
prefix func ++(inout x: Float80) -> Float80 {
x += 1
return x
}
postfix func ++(inout x: Float80) -> Float80 {
x += 1
return (x - 1)
}
prefix func ++<T : _Incrementable>(inout i: T) -> T {
i = i.successor()
return i
}
postfix func ++<T : _Incrementable>(inout i: T) -> T {
let y = i
i = i.successor()
return y
}
// Decrement
prefix func --(inout x: Int) -> Int {
x -= 1
return x
}
postfix func --(inout x: Int) -> Int {
x -= 1
return (x + 1)
}
prefix func --(inout x: UInt) -> UInt {
x -= 1
return x
}
postfix func --(inout x: UInt) -> UInt {
x -= 1
return (x + 1)
}
prefix func --(inout x: Int8) -> Int8 {
x -= 1
return x
}
postfix func --(inout x: Int8) -> Int8 {
x -= 1
return (x + 1)
}
prefix func --(inout x: UInt8) -> UInt8 {
x -= 1
return x
}
postfix func --(inout x: UInt8) -> UInt8 {
x -= 1
return (x + 1)
}
prefix func --(inout x: Int16) -> Int16 {
x -= 1
return x
}
postfix func --(inout x: Int16) -> Int16 {
x -= 1
return (x + 1)
}
prefix func --(inout x: UInt16) -> UInt16 {
x -= 1
return x
}
postfix func --(inout x: UInt16) -> UInt16 {
x -= 1
return (x + 1)
}
prefix func --(inout x: Int32) -> Int32 {
x -= 1
return x
}
postfix func --(inout x: Int32) -> Int32 {
x -= 1
return (x + 1)
}
prefix func --(inout x: UInt32) -> UInt32 {
x -= 1
return x
}
postfix func --(inout x: UInt32) -> UInt32 {
x -= 1
return (x + 1)
}
prefix func --(inout x: Int64) -> Int64 {
x -= 1
return x
}
postfix func --(inout x: Int64) -> Int64 {
x -= 1
return (x + 1)
}
prefix func --(inout x: UInt64) -> UInt64 {
x -= 1
return x
}
postfix func --(inout x: UInt64) -> UInt64 {
x -= 1
return (x + 1)
}
prefix func --(inout x: Double) -> Double {
x -= 1
return x
}
postfix func --(inout x: Double) -> Double {
x -= 1
return (x + 1)
}
prefix func --(inout x: Float) -> Float {
x -= 1
return x
}
postfix func --(inout x: Float) -> Float {
x -= 1
return (x + 1)
}
prefix func --(inout x: Float80) -> Float80 {
x -= 1
return x
}
postfix func --(inout x: Float80) -> Float80 {
x -= 1
return (x + 1)
}
prefix func --<T : BidirectionalIndexType>(inout i: T) -> T {
i = i.predecessor()
return i
}
postfix func --<T : BidirectionalIndexType>(inout i: T) -> T {
let y = i
i = i.predecessor()
return y
}
Solution 3
Apple has removed the ++
and made it much simpler with the another old traditional way.
Instead of ++
, you need to write +=
.
Example:
var x = 1
//Increment
x += 1 //Means x = x + 1
Similarly for decrement operator --
, you need to write -=
Example:
var x = 1
//Decrement
x -= 1 //Means x = x - 1
For for
loops:
Increment Example:
Instead of
for var index = 0; index < 3; index ++ {
print("index is \(index)")
}
You can write:
//Example 1
for index in 0..<3 {
print("index is \(index)")
}
//Example 2
for index in 0..<someArray.count {
print("index is \(index)")
}
//Example 3
for index in 0...(someArray.count - 1) {
print("index is \(index)")
}
Decrement Example:
for var index = 3; index >= 0; --index {
print(index)
}
You can write:
for index in 3.stride(to: 1, by: -1) {
print(index)
}
//prints 3, 2
for index in 3.stride(through: 1, by: -1) {
print(index)
}
//prints 3, 2, 1
for index in (0 ..< 3).reverse() {
print(index)
}
for index in (0 ... 3).reverse() {
print(index)
}
Hope this helps!
Solution 4
Chris Lattner has gone to war against ++ and --. He writes, “Code that actually uses the result value of these operators is often confusing and subtle to a reader/maintainer of code. They encourage “overly tricky” code which may be cute, but difficult to understand….While Swift has well defined order of evaluation, any code that depended on it (like foo(++a, a++)) would be undesirable even if it was well-defined…these fail the metric of “if we didn’t already have these, would we add them to Swift 3?””
Apple wanted to keep swift a clean, clear, non-confusing and straight-to-the-point language. And so they deprecated ++ and -- keyword.
Solution 5
The Fix-it feature
of Xcode gives clear answer to this.
Replace ++ increment operator
with old-fashioned value += 1
(short-hand operator) and -- decrement operator
with value -= 1
Comments
-
Oleg Gordiichuk over 2 years
I am looking at Xcode 7.3 notes and I notice this issue.
The ++ and -- operators have been deprecated
Could some one explain why it is deprecated? And am I right that in new version of Xcode now you going to use instead of
++
thisx += 1
;Example:
for var index = 0; index < 3; index += 1 { print("index is \(index)") }
-
Oleg Gordiichuk about 8 yearsIn other words this operation is too expensive to be used ?
-
Dániel Nagy about 8 yearsgithub.com/apple/swift-evolution/blob/master/proposals/… here you can read about it, but it's not because it's expensive, but rather language design.
-
Oleg Gordiichuk about 8 yearsSo as i andersen Swift going to drop support of the C-style features
-
Fogmeister about 8 years@OlegGordiichuk no, they are not "dropping C-style features". They are designing a new language and get to decide what fits and what doesn't. If a C-style function doesn't fit then they will drop it as there are better alternatives that match the language they are developing.
-
mah about 8 years@OlegGordiichuk It seems to me that swift's design is really not oriented towards existing developers (or those with passion towards being developers) but rather towards those that may not have the inclination to be developers -- as a way of enabling good design from people that don't have the developer thought process. This is certainly not to disparage the many excellent developers that have decided to move towards the language! It's just my opinion that those developers are not the language's target audience.
-
Dániel Nagy about 8 years@OlegGordiichuk well I would say they want to emphasize that Swift is not a superset of C unlike Objective-C.
-
Fogmeister about 8 years@mah a lot of what you said just doesn't make sense at all. "Not oriented towards existing developers" in what way? In the same way that Java is not oriented towards PHP developers? "oriented towards those that may not have the inclination to be developers"? Yeah, because all those non-developers out there are biting the hand off with protocol oriented programming and generics. "A way of enabling good design" just take a look at SO, you will see that no programming language can "enable good design".
-
mah about 8 years@Fogmeister my opinion is primarily based on the oversimplification of things, including removal of pre/post operators like this - I don't find them confusing and while I may be under the "curse of knowledge", it's difficult for me to see how other developers would get confused by them. I agree, languages do not enable good design per se, but by removing features that developers have used for years successfully, the language certainly gets easier for non-developers to pick up. Apple benefits by having these newbies-to-development writing iDevice apps, so who do you think is their target?
-
Fogmeister about 8 years@mah like I said further above. They are designing the language from scratch. They are not taking what has been done before and changing it. x++ makes sense to me. But what is the value of x after this...
x = x - ++x
? It add complexity where it isn't needed. Why isx += 1
so much worse? Like the accepted answer said, it's primary use was in C-style for loops. But for loops have a much better implementation in Swift that doesn't require it so it is no longer needed. Your argument seems to come down to "I dont like it because it's not what I'm used to" Of course it isn't. Its a new language. -
mah about 8 years@Fogmeister Your argument seems to come down to "I dont like it because it's not what I'm used to" is you reading far more into things than I've said.... I neither dislike nor like it; I'm highly neutral and I have no judgement about the language at all. I invite you to attack my opinion, but I prefer you to first take time to see what my opinion is, which is about the motivation of the language's simplification, not about the details of it. I don't see that you have anything to be so defensive about.
-
user3441734 about 8 yearsI thing, the real answer is number 6. That is OK, we (former C, Java, ... programmers) are flexible enough :-). Generally, for the real world, mutation, crossover and selection is enough. I, You and Cris too, we are all results of those three operators ...
-
Nicolas Miari about 8 yearsYou mean elegant as in "you have to remember all the subtleties of the C programming language, otherwise it is not immediately obvious if the first call returns 1 or 2"? I think we can all spare a few extra lines of code in exchange for not spending several minutes scratching our heads trying to find a bug cause by a silly mistake...
-
mcatach about 8 yearsClean? Look at this callback hell and call it clean? I disagree... And I'd add: leave the ++ & -- alone
-
mad_manny about 8 yearssomething like
...for i in 0.stride(to: 10, by: 2)...
or...for i in (1...10).reverse()...
is clean?! -
Echelon about 8 yearsPoint 5: Those were always implementation-dependent in C, and no-one with any sense ever did them. Simply define the behaviour and we'll get used to it. Better than having to go back and change perfectly good old code for no real reason.
-
Nicolas Miari about 8 yearsI like point 3. You can't be shackled to the contract of legacy forever. I love C but you are creating a new programming language; makes sense to start with the slate as clean as you need it to be.
-
Nicolas Miari about 8 yearsThey haven't replaced anything;
+=
was there all along. -
Sohil R. Memon about 8 years@NicolasMiari Yeah just editing with the much better format
-
Sohil R. Memon about 8 years@NicolasMiari Can you please check now?
-
Zigii Wong about 8 yearsWhat about
++i
and--i
? -
Adrian Bartholomew almost 8 yearsI agree. The 'clean' argument is fundamentally contradictory wrt to the rest of Swift. Coming from Objective-C, which is objectively unclean, it's quite difficult to accept 'clean' as an Apple language goal.
-
csga5000 almost 8 yearsIt's cause apple likes to force you to think like they do. I think it's perfectly fine and used anywhere you need to increment or decriment a variable. It's not something you "have to learn" you'll do fine without it. And #5 is just poorly written code, the likes of which I have never seen. So #6 it is. Depricating it is enough to make me scratch my head and do a google search, so thanks for wasting my time Chris.
-
Alnitak almost 8 yearsI don't like your
return (x - 1)
for the postfix operators - IMHO's it's cleaner to maintain the semantics that they return (a copy of) the original value rather than what you get if you dox + 1 - 1
-
0101 almost 8 yearsI don't like it either but I don't know about any other (better, cleaner) way of doing this. I don't fully understand your second point.
-
Alnitak almost 8 yearsWell, I'd just do
let y = x; x += 1; return y
- my latter point is over concerns that there may be edge cases relating to overflow where(x + 1) - 1 != x
-
0101 almost 8 yearsI see, I didn't want to do that just for the sake of creating another variable (or rather constant in this case). If we are talking about
Int
only then the result of(x + 1)
will be overflown which will interrupt execution and thereforeresult - 1
won't be even ran. Other datatypes likeDouble
for example, behave however differently so I need to investigate that. -
overactor almost 8 years@csga5000 That's quite a weak argument considering that you can just define the operator yourself if you really want to. It has nothing to do with apple wanting people to think like them. It simply doesn't fit the language. If the
++
didn't exist in C-style languages, no one in their right mind would look at the design of Swift 3.0 and think that a++
operator would be a nice addition to it. -
Ryan Poolos almost 8 yearsAlso worth pointing out that #5 being poorly written code is still ALOT of the code we deal with. The new changes make that code impossible. No more poorly written code is better than some poorly written code.
-
csga5000 almost 8 years@overactor First of all, I made arguments against all the points made for it, and you're picking one item and calling it a weak argument. Of course you could define the operator, but I would not think it a good practice. It could cause greater confusion to other developers on the project. My biggest argument is that deliberately removing the feature that previously existed and served a reasonable purpose is pointlessly causing slight confusion and costs people like me a few minutes of my time.
-
csga5000 almost 8 years@RyanPoolos Like I said, I've never see code written like that. And I've worked with some pretty awful code bases written by other companies or other developers. Not all of my code has been beautiful either, but none of it abuses the ++ operator in a confusing fashion such as that.
-
Amin Negm-Awad almost 8 yearsPoint 4: Is there really a better replacement for
--
in a C-style decrementing loop? ;-) -
Code Different almost 8 yearsThere is one:
for i in (0..<n).reverse() { ... }
-
Felipe Andrade over 7 yearsChris Lattner doesn't like it. :D
-
Tim Vermeulen over 7 yearsYou can use
defer
for this, too.defer { x += 1 }; return x
-
Agustí Sánchez over 7 yearsThose freaks at Apple are deleting useful features like the "++" operator and the headphone jack out of sectarian ideology. I don't see the guys behind Java and C# deleting the "++" operator, they have more common sense.
-
nickthedude over 7 yearsTry parsing json and swift and tell me how clean it is.
-
Joseph Junior Sfeir over 7 yearsI think the only really valid argument is point 3 (and 4 to some extent) - the rest is just subjective preference
-
clearlight over 7 years#5 is the only worthwhile reason I can see at this point to drop it, since it was included in earlier versions of Swift and was otherwise fairly harmless. Most programmers are (or should be) familiar with the convenient ++ and -- operators. Annoyingly I can't do
if (++pos % 3600 == origPos) { }
anymore but need to create an extra line. So it's not purely a positive to remove it. It has advantages and disadvantages. -
Bogdan about 7 yearsThey should have thought all the basic language details when they started it. You don't come with this change or any other changes in upcoming versions. It's bad enough to have to use frameworks where the API changes over a version increase, but to see this in a language syntax that's just ...
-
Orkhan Alikhanov almost 7 yearsCan you share the script that created this? or you did it yourself? :)
-
μολὼν.λαβέ over 6 yearswhy not use generics and write this in a few lines?
-
noamtm almost 6 yearsLike you, I don't like that they are removed; however, I wouldn't use it because it will confuse future programmers (that don't even know Java and C) who will think it's a core language feature. It's better to go in the way guided by the language. Still... +1 for showing that it's possible.
-
DawnSong over 5 years
i += 1
returnsVoid
, which is the most important point. So,++i
andi++
returnVoid
, too. -
DawnSong over 5 years
i += 1
returnsVoid
, which is the most important point. So,++i
andi++
returnVoid
, too. -
JeremyP over 5 years@DawnSong Why would they? When Swift had
++
and--
they did not returnVoid
. So why now? -
JeremyP over 5 years@0101 Things have moved on a bit since you wrote this answer. You could probably remove a lot of duplication by using making the operators generic over the new numeric protocols. Also, the index versions will probably no longer work.
-
DawnSong over 5 years@JeremyP If assignment has a value, so
if (a = 5)
is valid, anda = b++ + ++b
is valid too. They are confusing and lack readability. That's why Swift prefers thata = 5
is aVoid
, instead of 5. -
JeremyP over 5 years@DawnSong Why do you believe that the fact that the assignment operators have
Void
type means that the++
and--
operators should also haveVoid
type? -
timeSmith over 5 yearsThis isn't a new language, it's version 3; the slate is not clean; this is a breaking change to add a trivial language attribute. @nicolas-miari
-
Nicolas Miari over 5 years@timeSmith Swift is a new language. That they didn’t come around to doing “the right thing” until version 3, is merely incidential in my opinion. You don’t want to be another C++.
-
DawnSong over 5 years@JeremyP As we know,
++i
is identical toi+=1
, so if the latter have aVoid
return type, why++i
needs a return type? -
JeremyP over 5 years@DawnSong There's no law that says that
++i
must be identical toi += 1
. Indeed, in Swift 1 and 2, it was not. -
timeSmith over 5 years@NicolasMiari you said "…creating a new programming language; makes sense to start with the slate as clean as you need it to be." But this was a backward-incompatible change, to a ubiquitous feature, when the language was several years old, and when the language was on its 3rd (or 4th) major release version (4th because there was an effectively-public beta). I wasn't saying every language should have increment operators. I was saying the specific argument, that the language was new, is invalid.
-
DawnSong about 5 years@JeremyP If
++i
is not identical toi += 1
, it's really confusing. Why people love to confuse himself / herself? Swift loves simplicity, so I love Swift. -
JeremyP about 5 years@DawnSong No, it's not really confusing. They don't look the same so it's not confusing that they are not the same. If you get confused by this, Swift's generics model is going to be a bit of a shock.
-
DawnSong about 5 years@JeremyP Generics are very useful. Maybe the feature is not complete, but it will be. Results of many expressions composed by
++
depend on the compiler's implementation. So,++
is malicious. Am I clear? -
JeremyP about 5 years@DawnSong Generics are an incredible powerful feature even as they are now. But they can be very confusing until you grok them. As for
++
depending on the compiler implementation, there is only one compiler and it doesn't have++
. -
Devin Lane over 4 yearsI added
@discardableResult
to each of these functions to silence the warning about the return value being unused; otherwise exactly what I was looking for. -
Neph over 2 yearsUsing
++
displays the following error in Swift 5/Xcode 13:Cannot find operator '++' in scope; did you mean '+= 1'?
- so they know that people are going to try to use it. I fully agree with csga5000, reason 8 is simply: "You better deal with it and think like we do, even when it's an inconvenience like pressing 3 different keys that are pretty far apart on the keyboard, instead of just pressing the same key twice". Fitting for a company that won't even let you delete a file by pressing the "del" key. -
Azurlake over 2 yearsIt's all about thinking the way they like you to think. Not specific to the operator, but bending your mind much like when "you're holding it wrong". I can quickly come up with extremely difficult to "visually decode" valid swift code and that doesn't invalidate the syntax - just the same finding some poor examples of ++ or -- doesn't invalidate their use. They're just a tool. Use them wise and that's it - if they let you use them.
-
Chris Walken about 2 yearsUhhh…. What about the \n that comes at the end of var x = y - pretty sure it wasn’t the first day on the job for the guy that wrote the Swift parser.