本文轉載自:https://hicc.me/whats-new-in-swift-3-to-5-1/,本站轉載出於傳遞更多信息之目的,版權歸原做者或者來源機構全部。html
Hipo 2.0 重寫從 Swift 1的版本寫到2的版本,後續Hipo功能穩定,更新慢了不少……,Swift自己卻在長足的發展,5.0都已經發布了,本文對Swift 3.0 到Swift 5.1 的更新點作個總結。python
爲了方便閱讀,準備重新到舊的總結。git
下面全部的東西,都是來自 hackingwithswift.com 。github
// TODO:express
Swift 5.0 最重要的天然是 ABI Stability , 對此能夠看這篇 Swift ABI 穩定對咱們到底意味着什麼 。json
固然還有其餘的更新。swift
Result
類型SE-0235 提議的實現。用來在複雜對象中的錯誤處理。api
Result
類型有兩個帶泛型的枚舉成員 success
和 failure
,並且 failure
的泛型必須遵循Swift的 Error
類型。數組
常規的使用安全
enum NetworkError: Error { case badURL } import Foundation func fetchUnreadCount1(from urlString: String, completionHandler: @escaping (Result<Int, NetworkError>) -> Void) { guard let url = URL(string: urlString) else { completionHandler(.failure(.badURL)) return } // complicated networking code here print("Fetching \(url.absoluteString)...") completionHandler(.success(5)) } fetchUnreadCount1(from: "https://www.hackingwithswift.com") { result in switch result { case .success(let count): print("\(count) unread messages.") case .failure(let error): print(error.localizedDescription) } }
首先, Result
有個 get()
方法,要麼返回成功值,要麼拋出錯誤。那麼能夠這麼使用。
fetchUnreadCount1(from: "https://www.hackingwithswift.com") { result in if let count = try? result.get() { print("\(count) unread messages.") } }
再次, Result
能夠接受一個閉包來初始化,若是閉包成功返回,就會把它放到 success
的一邊,若是拋出錯誤,就放到 failure
的一邊。
let result = Result { try String(contentsOfFile: someFile) }
最後,你可使用你本身的錯誤枚舉,可是Swift官方建議,你說用 Swift.Error
來做爲 Error
的參數。
「it’s expected that most uses of Result will use Swift.Error as the Error type argument.」
SE-0200 引入了,使用 #
來包裹的Raw字符串,裏面的字符不會作處理,特別是一些轉義字符。
差值須要這樣作
let answer = 42 let dontpanic = #"The answer to life, the universe, and everything is \#(answer)."#
這個對於正則的特別好用
let regex1 = "\\\\[A-Z]+[A-Za-z]+\\.[a-z]+" let regex2 = #"\\[A-Z]+[A-Za-z]+\.[a-z]+"#
SE-0228 提案改進了Swift的字符串插值,讓其更高效和自由。
struct User { var name: String var age: Int } extension String.StringInterpolation { mutating func appendInterpolation(_ value: User) { appendInterpolation("My name is \(value.name) and I'm \(value.age)") } } let user = User(name: "Guybrush Threepwood", age: 33) print("User details: \(user)") // User details: My name is Guybrush Threepwood and I'm 33,
// TODO: 更多使用,須要多研究
SE-0216 增長了 @dynamicCallable
屬性,來支持方法的動態調用,相似 @dynamicMemberLookup
。
你能夠將
struct RandomNumberGenerator { func generate(numberOfZeroes: Int) -> Double { let maximum = pow(10, Double(numberOfZeroes)) return Double.random(in: 0...maximum) } }
轉變爲
@dynamicCallable struct RandomNumberGenerator { func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Double { let numberOfZeroes = Double(args.first?.value ?? 0) let maximum = pow(10, numberOfZeroes) return Double.random(in: 0...maximum) } } let random = RandomNumberGenerator() let result = random(numberOfZeroes: 0)
@dynamicCallable
參數
withArguments
,你可使用任何遵循 ExpressibleByArrayLiteral
的類型,例如 數組,數組切片,set等withKeywordArguments
,使用任何遵循 ExpressibleByDictionaryLiteral
的類型,例如,字典,和key value 對,更多 KeyValuePairs
能夠的看這裏, 什麼是KeyValuePairs?withKeywordArguments
而不是 withArguments
,你仍然按照無參數標籤的方式使用,只是key是空字符串。withKeywordArguments
或者 withArguments
標記爲拋出錯誤,調用類型也會拋出錯誤。@dynamicCallable
SE_0192 的實現。
有時候枚舉的switch中使用 default
來防治出錯,但不會真正的使用,可是若是將來加了新的 case
,那些處理地方就會遺漏。如今能夠添加 @unknkow
來出觸發Xcode的提示。
func showNew(error: PasswordError) { switch error { case .short: print("Your password was too short.") case .obvious: print("Your password was too obvious.") @unknown default: print("Your password wasn't suitable.") } }
這樣,若是若是代碼中,沒有處理乾淨PasswordError ( switch
block is no longer exhaustive),就會告警.
try?
抹平嵌套可選struct User { var id: Int init?(id: Int) { if id < 1 { return nil } self.id = id } func getMessages() throws -> String { // complicated code here return "No messages" } } let user = User(id: 1) let messages = try? user?.getMessages()
上面的例子中,Swift 4.2以及以前的, message
會是 String??
, 這樣就不太合理,Swift 5中,就能返回抹平的 String?
SE-0225 添加了, isMultiple(of:)
來檢查整數是否爲偶數, 和 if rowNumber % 2 == 0
效果同樣。
let rowNumber = 4 if rowNumber.isMultiple(of: 2) { print("Even") } else { print("Odd") }
compactMapValues()
方法SE-0218 ,爲字典添加了 compactMapValues()
方法,這個就像結合了,數組 compactMap()
方法(遍歷成員,判斷可選的值,而後丟棄nil成員)和字典的 mapValues()
方法(只轉換字典的value)。
let times = [ "Hudson": "38", "Clarke": "42", "Robinson": "35", "Hartis": "DNF" ] let finishers1 = times.compactMapValues { Int($0) } let finishers2 = times.compactMapValues(Int.init) let people6 = [ "Paul": 38, "Sophie": 8, "Charlotte": 5, "William": nil ] let knownAges = people6.compactMapValues { $0 } print("compactMapValues, \(finishers1), \(finishers2),\(knownAges)") // compactMapValues, ["Clarke": 42, "Robinson": 35, "Hudson": 38], ["Robinson": 35, "Clarke": 42, "Hudson": 38],["Charlotte": 5, "Sophie": 8, "Paul": 38]
SE-0220 , 引入了 count(where:)
函數,來計算遵循 Sequence
列表中知足條件成員的個數。
let scores = [100, 80, 85] let passCount = scores.count { $0 >= 85 } let pythons = ["Eric Idle", "Graham Chapman", "John Cleese", "Michael Palin", "Terry Gilliam", "Terry Jones"] let terryCount = pythons.count { $0.hasPrefix("Terry") }
CaseIterable
協議SE-0194 提議的實現,Swift4.2 增長了 CaseIterable
協議,可以給枚舉的 allCases
屬性自動產生全部的枚舉的數組。
enum Pasta: CaseIterable { case cannelloni, fusilli, linguine, tagliatelle } for shape in Pasta.allCases { print("I like eating \(shape).") }
固然還能夠自行實現
enum Car: CaseIterable { static var allCases: [Car] { return [.ford, .toyota, .jaguar, .bmw, .porsche(convertible: false), .porsche(convertible: true)] } case ford, toyota, jaguar, bmw case porsche(convertible: Bool) }
SE-0196 提議的實現。Swift 4.2提供這兩個提示,來讓Xcode在編譯時候做出提示
#warning #error
func encrypt(_ string: String, with password: String) -> String { #warning("This is terrible method of encryption") return password + String(string.reversed()) + password } struct Configuration { var apiKey: String { #error("Please enter your API key below then delete this line.") return "Enter your key here" } }
還能夠和 #if
配合使用。
#if os(macOS) #error("MyLibrary is not supported on macOS.") #endif
SE-0195 提議的實現。Swift 4.2提供了 @dynamicMemberLookup
的屬性,和 subscript(dynamicMember:)
陪着使用,實現動態的屬性的取值。
@dynamicMemberLookup struct Person5 { subscript(dynamicMember member: String) -> String { let properties = ["name": "Tylor Swift", "city" : "Nashville"] return properties[member, default: ""] } } let person5 = Person5() print("person5.name: \(person5.name)") print("person5.city: \(person5.city)") print("person5.favoriteIceCream: \(person5.favoriteIceCream)") // person5.name: Tylor Swift // person5.city: Nashville // person5.favoriteIceCream:
固然也有相似多態的用法。
@dynamicMemberLookup struct Person5 { subscript(dynamicMember member: String) -> String { let properties = ["name": "Tylor Swift", "city" : "Nashville"] return properties[member, default: ""] } subscript(dynamicMember member: String) -> Int { let properties = ["age": 26, "height": 178] return properties[member, default: 0] } } let person5 = Person5() print("person5.age: \(person5.age)") let age: Int = person5.age print("person5.age2: \(age)") // person5.age: // person5.age2: 26
注意你須要指定明確指定類型,Swift才能正確使用。
並且若是已經有存在屬性,動態屬性將不會生效
struct Singer { public var name = "Justin Bieber" subscript(dynamicMember member: String) -> String { return "Taylor Swift" } } let singer = Singer() print(singer.name) // Justin Bieber
@dynamicMemberLookup
能夠用在協議,結構體,枚舉,類,甚至標註爲 @objc
的類,以及它們的繼承者。
例如,陪着協議的使用,你能夠這樣用
@dynamicMemberLookup protocol Subscripting { } extension Subscripting { subscript(dynamicMember member: String) -> String { return "This is coming from the subscript" } } extension String: Subscripting { } let str = "Hello, Swift" print(str.username)
Chris Lattner提議中的例子頗有意義,
@dynamicMemberLookup enum JSON { case intValue(Int) case stringValue(String) case arrayValue(Array<JSON>) case dictionaryValue(Dictionary<String, JSON>) var stringValue: String? { if case .stringValue(let str) = self { return str } return nil } subscript(index: Int) -> JSON? { if case .arrayValue(let arr) = self { return index < arr.count ? arr[index] : nil } return nil } subscript(key: String) -> JSON? { if case .dictionaryValue(let dict) = self { return dict[key] } return nil } subscript(dynamicMember member: String) -> JSON? { if case .dictionaryValue(let dict) = self { return dict[member] } return nil } }
正常使用
let json = JSON.stringValue("Example") json[0]?["name"]?["first"]?.stringValue
若是用上述的寫法
json[0]?.name?.first?.stringValue
Swift 4.1引入了有條件地遵循協議
extension Array: Purchaseable where Element: Purchaseable { func buy() { for item in self { item.buy() } } }
可是在Swift 4.1中,若是你要肯定對象是否遵循某個協議,會報錯。Swift 4.2 修復了這個問題
let items: Any = [Book(), Book(), Book()] if let books = items as? Purchaseable { books.buy() }
還有,Swift 內置的類型,可選,數組,字典,區間,若是它們的成員遵循 Hashable
,那麼它們也會自動遵循 Hashable
。
shuffling
SE-0202 提議的實現。Swift 4.2提供了原生的隨機數方法。意味着你不須要使用 arc4random_uniform()
或者GameplayKit來實現了。
let randomInt = Int.random(in: 1..<5) let randomFloat = Float.random(in: 1..<10) let randomDouble = Double.random(in: 1...100) let randomCGFloat = CGFloat.random(in: 1...1000) let randomBool = Bool.random()
SE-0202一樣還提議了 shuffle()
和 shuffled()
var albums = ["Red", "1989", "Reputation"] // shuffle in place albums.shuffle() // get a shuffled array back let shuffled = albums.shuffled()
還有 randomElement()
方法。
if let random = albums.randomElement() { print("The random album is \(random).") }
SE-0206 的實現,讓你更簡單的爲自建類型使用 Hashable
協議。
Swift 4.1 可以爲遵循 Hashable
協議的類型自動生成hash值。可是若是你須要自行實現仍然須要寫很多代碼。
Swift 4.2 引入了 Hasher
結構,提供了隨機種子,和通用的hash函數來簡化過程
struct iPad: Hashable { var serialNumber: String var capacity: Int func hash(into hasher: inout Hasher) { hasher.combine(serialNumber) } } let first = iPad(serialNumber: "12345", capacity: 256) let second = iPad(serialNumber: "54321", capacity: 512) var hasher = Hasher() hasher.combine(first) hasher.combine(second) let hash = hasher.finalize()
SE-0207 的實現,提供了 allSatisfy()
方法來檢測數組中全部的元素是否都知足條件。
let scores = [85, 88, 95, 92] let passed = scores.allSatisfy { $0 >= 85 }
SE-0197 提供一個全新的 removeAll(where:)
方法,以此來提供一個更高效,會操做原數據的相似 filter
的方法。
var pythons = ["John", "Michael", "Graham", "Terry", "Eric", "Terry"] pythons.removeAll { $0.hasPrefix("Terry") } print(pythons)
SE-0199 提供了,對 Bool
的 toggle()
方法,相似
extension Bool { mutating func toggle() { self = !self } }
Swift 4.2 你能夠這樣
var loggedIn = false loggedIn.toggle()
Equatable
和 Hashable
協議類和結構體作可比較,須要本身手動實現。
struct Person: Equatable { var firstName: String var lastName: String var age: Int var city: String static func ==(lhs: Person, rhs: Person) -> Bool { return lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName && lhs.age == rhs.age && lhs.city == rhs.city } } let person1 = Person(firstName: "hicc", lastName: "w", age: 20, city: "shenzhen") let person2 = Person(firstName: "hicc", lastName: "w", age: 20, city: "shenzhen") print("person1 1 == person2 : \(person1 == person2)") // person1 1 == person2 : true
Swift 4.1 提供了 Equatable
的協議,它會自動的生成 ==
方法。
固然你仍是能夠本身實現 ==
方法(例如,業務有id之類的屬性)。
還有以前實現一個對象的hash值也是一件麻煩的事情,你可能須要手動實現相似:
var hashValue: Int { return firstName.hashValue ^ lastName.hashValue &* 16777619 }
Swift 4.1 提供了 Hashable
的協議,能夠自動生成 hashValue
,你也仍是能夠自行實現。
struct Person2: Equatable, Hashable { var firstName: String var lastName: String var age: Int var city: String } let person11 = Person2(firstName: "hicc", lastName: "w", age: 20, city: "shenzhen") let person22 = Person2(firstName: "hicc", lastName: "w", age: 20, city: "shenzhen") print("person11 1 == person22 : \(person11 == person22), \(person11.hashValue)") // person11 1 == person22 : true, 5419288582170212869
Codable
協議,Key值轉化策略Swift 4提供了很方便的 Codable
協議,可是它使用下劃線snake_case而不是駝峯式的方式來轉化Key,不太自由。
Swift 4.1 中針對這種狀況,提供了 keyDecodingStrategy
,以及 keyEncodingStrategy
屬性(默認 .useDefaultKeys
)來解決這些問題。
let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase do { let macs = try decoder.decode([Mac].self, from: jsonData) print(macs) } catch { print(error.localizedDescription) } let encoder = JSONEncoder() encoder.keyEncodingStrategy = .convertToSnakeCase let encoded = try encoder.encode(someObject)
Swift 4.1 實現了 SE-0143 的提議,允許你類型在某下狀況下才遵循某個協議。
extension Array: Purchaseable where Element: Purchaseable { func buy() { for item in self { item.buy() } } }
這樣會讓你的代碼,更加的安全。以下代碼Swift中會拒絕編譯,由於其未遵循 Coodable
協議.
import Foundation struct Person { var name = "Taylor" } var people = [Person()] var encoder = JSONEncoder() try encoder.encode(people)
Swift 4.1實現了 SE-0157 提議,在遞歸協議中,關聯類型能夠被定義它的協議所限制。
protocol Employee { associatedtype Manager: Employee var manager: Manager? { get set } }
// TODO: 如今感覺不太清楚,後續有深刻了解在補充。
canImport
函數SE-0075 提議的實現。Swift 4.1引入了 canImport
函數,讓你能夠檢查某個模塊可否被導入。
#if canImport(SpriteKit) // this will be true for iOS, macOS, tvOS, and watchOS #else // this will be true for other platforms, such as Linux #endif
以前還有相似的方法
#if !os(Linux) // Matches macOS, iOS, watchOS, tvOS, and any other future platforms #endif #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) // Matches only Apple platforms, but needs to be kept up to date as new platforms are added #endif
targetEnvironment
函數SE-0190 提議的實現,Swift 4.1 提供了 targetEnvironment
函數,來檢測是模擬器仍是真實的硬件。
#if targetEnvironment(simulator) // code for the simulator here #else // code for real devices here #endif
flatMap以前一個頗有用的做用是可以過濾數組中爲 nil
的元素,Swift 4.2重命名爲指意明確,更強大的 compactMap
let array = ["1", "2", "Fish"] let numbers = array.compactMap { Int($0) } // [1, 2]
Coodable
協議Swift 4以前使用 NSCoding
來作encoding和decoding的事情,可是須要一些模版代碼,也容易出錯,Swift 4中 Coodable
協議就是爲這個而存在。
使用起來簡單到難以想象。
struct Language: Codable { var name: String var version: Int } let swift = Language(name: "Swift", version: 4)
完整的使用
let encoder = JSONEncoder() if let encoded = try? encoder.encode(swift) { if let json = String(data: encoded, encoding: .utf8) { print("swift strng\(json)") } let decoder = JSONDecoder() if let decoded = try? decoder.decode(Language.self, from: encoded) { print("Swift name: \(decoded.name)") } }
跨越多行的字符串可使用 """
來包裹。
let quotation = """ The White Rabbit put on his spectacles. "Where shall I begin, please your Majesty?" he asked. "Begin at the beginning," the King said gravely, "and go on till you come to the end; then stop." """
keypaths
keypaths
是指對屬性的引用而不去真正讀取屬性的值。
struct Crew { var name: String var rank: String } struct Starship { var name: String var maxWarp: Double var captain: Crew } let janeway = Crew(name: "Kathryn Janeway", rank: "Captain") let voyager = Starship(name: "Voyager", maxWarp: 9.975, captain: janeway) let nameKeyPath = \Starship.name let maxWarpKeyPath = \Starship.maxWarp let captainName = \Starship.captain.name let starshipName = voyager[keyPath: nameKeyPath] let starshipMaxWarp = voyager[keyPath: maxWarpKeyPath] let starshipCaptain = voyager[keyPath: captainName] print("starshipName \(starshipName),\(starshipCaptain)") // starshipName Voyager, Kathryn Janeway
Swift 4改進了字典的諸多函數。
filter map mapValues grouping default
let cities = ["Shanghai": 24_256_800, "Karachi": 23_500_000, "Beijing": 21_516_000, "Seoul": 9_995_000]; let massiveCities = cities.filter { $0.value > 10_000_000 } let populations = cities.map { $0.value * 2 } let roundedCities = cities.mapValues { "\($0 / 1_000_000) million people" } let groupedCities = Dictionary(grouping: cities.keys) { $0.first! } let groupedCities2 = Dictionary(grouping: cities.keys) { $0.count } var favoriteTVShows = ["Red Dwarf", "Blackadder", "Fawlty Towers", "Red Dwarf"] var favoriteCounts = [String: Int]() for show in favoriteTVShows { favoriteCounts[show, default: 0] += 1 } print("dic\(massiveCities),\n\(populations),\n\(roundedCities),\n\(groupedCities),\n\(groupedCities2),\n\(favoriteCounts)") // dic["Shanghai": 24256800, "Beijing": 21516000, "Karachi": 23500000], // [43032000, 47000000, 19990000, 48513600], ///["Beijing": "21 million people", "Karachi": "23 million people", "Seoul": "9 million people", "Shanghai": "24 million people"], // ["S": ["Seoul", "Shanghai"], "B": ["Beijing"], "K": ["Karachi"]], // [8: ["Shanghai"], 5: ["Seoul"], 7: ["Beijing", "Karachi"]], // ["Blackadder": 1, "Fawlty Towers": 1, "Red Dwarf": 2]
字符串是Collection類型,這樣就有了諸多便利的方法。
let quote = "It is a truth universally acknowledged that new Swift versions bring new features." let reversed = quote.reversed() for letter in quote { print(letter) }
Swift 4 支持了單側區間, 缺失的一邊爲0或者爲集合的盡頭
let characters = ["Dr Horrible", "Captain Hammer", "Penny", "Bad Horse", "Moist"] let bigParts = characters[..<3] let smallParts = characters[3...] print(bigParts) print(smallParts) // ["Dr Horrible", "Captain Hammer", "Penny"] // ["Bad Horse", "Moist"]
Swift支持對擴展作限制。
extension Collection where Iterator.Element: Comparable { func lessThanFirst() -> [Iterator.Element] { guard let first = self.first else { return [] } return self.filter { $0 < first } } } let items = [5, 6, 10, 4, 110, 3].lessThanFirst() print(items)
extension Array where Element: Comparable { func lessThanFirst() -> [Element] { guard let first = self.first else { return [] } return self.filter { $0 < first } } } let items = [5, 6, 10, 4, 110, 3].lessThanFirst() print(items)
上述3.0的對擴展的限制都是經過協議實現。Swift 3.1 支持使用類型來限制。
extension Array where Element == Int { func lessThanFirst() -> [Int] { guard let first = self.first else { return [] } return self.filter { $0 < first } } } let items = [5, 6, 10, 4, 110, 3].lessThanFirst() print(items)
Swift 3.1支持了嵌套類型中使用泛型。
struct Message<T> { struct Attachment { var contents: T } var title: T var attachment: Attachment }
prefix(while:)
, drop(while:)
兩個方法prefix(while:)
: 遍歷全部元素,直到遇到不知足條件的元素 ,而且返回知足的元素drop(while:)
: 就是返回 prefix(while:)
相反的就好。let names = ["Michael Jackson", "Michael Jordan", "Michael Caine", "Taylor Swift", "Adele Adkins", "Michael Douglas"] let prefixed = names.prefix { $0.hasPrefix("Michael") } print(prefixed) let dropped = names.drop { $0.hasPrefix("Michael") } print(dropped)
Swift特色是函數能夠分別制定參數標籤(argument label)和參數名稱(parameter name)
func someFunction(argumentLabel parameterName: Int) { } // 使用必須帶上參數標籤 someFunction(argumentLabel: 1) // 若是不指定,參數名稱能夠做爲菜參數標籤 func someFunction(firstParameterName: Int, secondParameterName: Int) { } someFunction(firstParameterName: 1, secondParameterName: 2)
若是你不想使用參數標籤,可使用 _
代替
func someFunction(_ firstParameterName: Int, secondParameterName: Int) { } someFunction(1, secondParameterName: 2)
主要是一些內置對象,以及和平臺相關的精簡,讓代碼更加易讀。
// Swift 2.2 let blue = UIColor.blueColor() let min = numbers.minElement() attributedString.appendAttributedString(anotherString) names.insert("Jane", atIndex: 0) UIDevice.currentDevice() // Swift 3 let blue = UIColor.blue let min = numbers.min() attributedString.append(anotherString) names.insert("Jane", at: 0) UIDevice.current
以及
// 第一行是Swift 2.2 // 迪爾汗是Swift 3 " Hello ".stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet()) " Hello ".trimmingCharacters(in: .whitespacesAndNewlines) "Taylor".containsString("ayl") "Taylor".contains("ayl") "1,2,3,4,5".componentsSeparatedByString(",") "1,2,3,4,5".components(separatedBy: ",") myPath.stringByAppendingPathComponent("file.txt") myPath.appendingPathComponent("file.txt") "Hello, world".stringByReplacingOccurrencesOfString("Hello", withString: "Goodbye") "Hello, world".replacingOccurrences(of: "Hello", with: "Goodbye") "Hello, world".substringFromIndex(7) "Hello, world".substring(from: 7) "Hello, world".capitalizedString "Hello, world".capitalized
以及, lowercaseString
-> lowercased()
, uppercaseString
-> uppercased()
dismissViewControllerAnimated(true, completion: nil) dismiss(animated: true, completion: nil) dismiss(animated: true) prepareForSegue() override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?)
正如標題說的,一方面這是Swift推薦的用法,另外就是內置對象的變化
UIInterfaceOrientationMask.Portrait // old UIInterfaceOrientationMask.portrait // new NSTextAlignment.Left // old NSTextAlignment.left // new SKBlendMode.Replace // old SKBlendMode.replace // new
還有就是Swift可選類型是經過枚舉來實現的
enum Optional { case None case Some(Wrapped) }
若是使用 .Some
來處理可選,也須要更改
for case let .some(datum) in data { print(datum) } for case let datum? in data { print(datum) }
大致來講就是讓C函數使用更加的Swift
// Swift 2.2 let ctx = UIGraphicsGetCurrentContext() let rectangle = CGRect(x: 0, y: 0, width: 512, height: 512) CGContextSetFillColorWithColor(ctx, UIColor.redColor().CGColor) CGContextSetStrokeColorWithColor(ctx, UIColor.blackColor().CGColor) CGContextSetLineWidth(ctx, 10) CGContextAddRect(ctx, rectangle) CGContextDrawPath(ctx, .FillStroke) UIGraphicsEndImageContext() // Swift 3 if let ctx = UIGraphicsGetCurrentContext() { let rectangle = CGRect(x: 0, y: 0, width: 512, height: 512) ctx.setFillColor(UIColor.red.cgColor) ctx.setStrokeColor(UIColor.black.cgColor) ctx.setLineWidth(10) ctx.addRect(rectangle) ctx.drawPath(using: .fillStroke) UIGraphicsEndImageContext() }
以及
// 第一行是Swift 2.2 // 第二行是Swift 3 CGAffineTransformIdentity CGAffineTransform.identity CGAffineTransformMakeScale(2, 2) CGAffineTransform(scaleX: 2, y: 2) CGAffineTransformMakeTranslation(128, 128) CGAffineTransform(translationX: 128, y: 128) CGAffineTransformMakeRotation(CGFloat(M_PI)) CGAffineTransform(rotationAngle: CGFloat(M_PI))
這部分屬於Swift更加語義化的改進,到如今5.1的時候一直在改進,目前[官網最近的規範]([Swift.org - API Design Guidelines] https://swift.org/documentation/api-design-guidelines/ )方法的部分是:
x.distance(to: y)
, i.successor()
print(x)
, x.sort()
, x.append(y)
ed
(一般是,不修改原數據,而是返回新的),有修改的使用如今時 ing
。from
。
以上所述就是小編給你們介紹的《Swift 3到5.1新特性整理》,但願對你們有所幫助,若是你們有任何疑問請給我留言,小編會及時回覆你們的。在此也很是感謝你們對 碼農網 的支持!