Monday Apple announced Swift 2, and just about everything announced is an extremely welcome change. This post is a summary of Chris Lattner’s discussion in the WWDC video “What’s new in Swift”. Now, let’s run through them…
Fundamentals
enums can now be printed to the console and show the actually value instead of just (enum value). Additionally, println is now just print. If you have ever used log debugging to figure out a problem involving enum values, rejoice!
I tested this and saw that not only is the enum value is printed, but so is the entire context of when and where the print() function is called.
enums can now support multiple types, so long to Box!
enum<T1, T2> { case First(T1) case Second(T2) }
The do keyword:
do { //... } while(someVar<5) // Can now be represented as: repeat { //... }
Option Sets can now use a standard Set type in Swift 2.0
viewOptions = .Repeat | .CurveEaseIn viewOptions = nil // Can now be represented as a set: viewOptions = [.Repeat, .CurveEaseIn] viewOptions = []
We can also create our own set types
(Default implementations in protocols)
struct MyStyle : OptionSetType { let rawValue: Int static let Bold = MyStyle(rawValue: 1) static let Italic = MyStyle(rawValue: 2) } iStyle.style = [] iStyle.style = [.Bold, .Italic] if iStyle.style.contains(.Bold) { //... }
Function arguments now behave the same way, regardless of if they are global functions, or methods on a data structure.
So now, you provide arguments labels on functions by default:
func myFunc(name: String, age: Int) { ... } myFunc("John", age: 35)
The # syntax is now gone, previously used to make the external argument name the same as the internal argument name.
In tests, public and internal are visible, via running a special run mode.
Pattern Matching
Added the guard statement which exits the scope in the else statement.
guard let name = json["name"] as? String else { return .Second("missing name") } // You can also combine this is to complex guards guard let name = json["name"] as? String, let year = json["year"] as? Int else return .Second("bad input") } // name and year are now String and Int types, not optionals! return .First(name, year)
Switch/case can now be used with inline if statements
switch bar() { case .SomeCase(let value) where value != 42: doThing(value) default: break } // Can now be represented as if case .SomeCase(let value) = bar() where value != 42 { doSomething(value) }
for in loops now support boolean filters and full pattern matching
for value in mySequence where value != "" { doThing(value) } for case .MyEnumCase(let value) in enumValues { doThing(value) }
BONUS: Example of try-catch for JSON vs invalid JSON
let jsonString = "{\"name\":\"Fred\", \"age\":40}" let badJsonString = "This really isn't valid JSON at all" let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding)! let badJsonData = badJsonString.dataUsingEncoding(NSUTF8StringEncoding)! do { // Try parsing some valid JSON let parsed = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments) print(parsed) // Try parsing some invalid JSON let otherParsed = try NSJSONSerialization.JSONObjectWithData(badJsonData, options: NSJSONReadingOptions.AllowFragments) print(otherParsed) } catch let error as NSError { // Catch fires here, with an NSErrro being thrown from the JSONObjectWithData method print("A JSON parsing error occurred, here are the details:\n \(error)") }
Will you be updating your tutorials?