What are the advantages Swift deprecates C-style for statement?
For details, see Swift Evolution - Remove C style for-loops
To quote the reasoning:
- Both
for-in
andstride
provide equivalent behavior using Swift-coherent approaches without being tied to legacy terminology.- There is a distinct expressive disadvantage in using for-loops compared to for-in in succinctness
for-loop
implementations do not lend themselves to use with collections and other core Swift types.- The
for-loop
encourages use of unary incrementors and decrementors, which will be soon removed from the language.- The semi-colon delimited declaration offers a steep learning curve from users arriving from non C-like languages
- If the for-loop did not exist, I doubt it would be considered for inclusion in Swift 3.
In summary: there are better ways (more expressive) than a C-style for-loop
to iterate in Swift.
Some examples:
for-in
over a range:
for i in 0 ..< 10 {
//iterate over 0..9
print("Index: \(i)")
}
for i in (0 ..< 10).reverse() {
//iterate over 9..0
print("Index: \(i)")
}
For arrays (and other sequences) we have many options (the following is not a complete list):
let array = ["item1", "item2", "item3"]
array.forEach {
// iterate over items
print("Item: \($0)")
}
array.reverse().forEach {
// iterate over items in reverse order
print("Item: \($0)")
}
array.enumerate().forEach {
// iterate over items with indices
print("Item: \($1) at index \($0)")
}
array.enumerate().reverse().forEach {
// iterate over items with indices in reverse order
print("Item: \($1) at index \($0)")
}
for index in array.indices {
// iterate using a list of indices
let item = array[index]
print("Item \(item) at index: \(index)")
}
Also note that if you are converting an array to another array, almost always you want to use array.filter
or array.map
or a combination of them.
For all Strideable
types we can use the stride
method to generate indices, for example:
for index in 10.stride(to: 30, by: 5) {
// 10, 15, 20, 25 (not 30)
print("Index: \(index)")
}
for index in 10.stride(through: 30, by: 5) {
// 10, 15, 20, 25, 30
print("Index: \(index)")
}
With arrays we can do:
for index in 0.stride(to: array.count, by: 2) {
// prints only every second item
let item = array[index]
print("Item \(item) at index: \(index)")
}
C-style for statement is deprecated and will be removed in a future
It was proposed and accepted to remove the ++ and -- operators from the Swift language in an upcoming release, therefore the warning you're seeing is to help you avoid these types of constructs in your code before it is removed. (Please reference the link for a full explanation as well as the advantages and disadvantages that they provide.)
Please note that C-Style loops will also be deprecated in the near future according to the following proposal: https://github.com/apple/swift-evolution/blob/master/proposals/0007-remove-c-style-for-loops.md
Not knowing exactly what kind of logic you need to implement I don't feel confident recommending a solution, however in accordance with the above proposals I would recommend that you may want to become familiar with the Swift for-in
and stride
statements. Or, as another person recommended, using a while
loop may also be appropriate.
c-style for statement deprecated with a twist
Might be best to go with a while loop:
var totalHeight: CGFloat = 0
while totalHeight < 2.0 * Configurations.sharedInstance.heightGame {
// Loop code goes here
totalHeight += backgroundImage.size.height
}
Converting a C-style for loop that uses division for the step to Swift 3
MartinR's solution is very generic and useful and should be part of your toolbox.
Another approach is to rephrase what you want: the powers of two from 7 down to 0.
for i in (0...7).reversed().map({ 1 << $0 }) {
print(i)
}
Replacement for c style loop with modulo
"while" should be the best:
var i = startIndex
while i != endIndex {
i = (i + 1) % arrCount
}
The ++ and -- operators have been deprecated Xcode 7.3
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?"
Advantage of telling the Swift Compiler an object's type, instead of inferring?
There’s zero runtime efficiency difference between the two. During compilation, Swift is inferring the type and writing it in for you. But once compiled, the two statements are identical.
It’s purely a question of readability and, occasionally, compiler efficiency.
Readability because in the statement let image: UIImage = UIImage()
, the double appearance of UIImage
is just clutter. And in cases of more complex types, it’s pretty much essential – no-one wants to write let keys: LazyForwardCollection<MapCollectionView<Dictionary<String, Int>, String>> = dict.keys
when they can write let keys = dict.keys
.
Compiler efficiency because occasionally you’ll find that a particularly ambiguous type (literals of literals are notorious for this) where lots of overloads need to be resolved can compile a lot faster if you explicitly name the type on the left-hand side. But this is just a question of how fast it compiles, not how fast it runs once it has compiled.
Deprecation and other attributes of methods in Swift, how?
Swift has an available
attribute that you can use for this. It's available arguments include
- introduced
- deprecated
- obsoleted
- message
- renamed.
Or for the example you gave:
@available(*, unavailable, message: "init is unavailable, use initWithFrame")
init() {
}
@available(*, deprecated, message: "use shareWithPars: instead")
class func shareWithParams(params: NSDictionary) {
}
For more information on these attributes, check out the Attributes section in The Swift Programming Language. (currently page 627)
++' is deprecated: it will be removed in Swift 3
Since Swift 2.2, you should use += 1
or -= 1
instead.
And after looking up Swift's evolution, there are some reasons for removing these operators:
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?"
Please check out Swift evolution for more info.
Related Topics
Uitextview Change Text Color of Specific Text
Uiview Background Color in Swift
How to Save Document to "Files" App in Swift
Setting Backgroundcolor of Custom Nsview
How to Get Multiple Lines of Stdin Swift Hackerrank
Swift (iOS 8 Sdk) Convert Unmanaged<Abmultivalueref> to Abmultivalueref
iOS - Add Image and Text in Title of Navigation Bar
Expand and Contract Tableview Cell When Tapped, in Swift
Swift Protocol Implements Equatable
How to Get Indexpath.Row in Cell.Swift
Pagination with Firebase Firestore - Swift 4
How to Display Image from a Url in Swiftui
Environmentobject VS Singleton in Swiftui
Swift: How to Get Everything After a Certain Set of Characters
Singleton and Init with Parameter