- Apple released the official version on March 29
Xcode 9.3
andSwift, 4.1
Let’s seeSwift, 4.1
What new features and new highlights have been brought - The test requires Xcode9.3, please make sure your Xcode is up to date with version 9.3
Swift, 4.1
withSwift, 4.0
Is source code compatible, so if you already useXcode
In theSwift Migrator
Migrate your project toSwift, 4.0
Then the new feature won’t break your code- The following in
Xcode9.3
Let’s go ahead and create a new onePlayground
Engineering, testing our code
Conditional Conformance
- Conditional conformance Protocol conformance of generic types whose type parameters satisfy specific conditions [SE-0143]
- In Swift 4, if the element type of array, dictionary, or optional type follows
Equatable
You can compare arrays, dictionaries, and optional types as shown in the following example:
// An array of type Int
let arr1 = [1.2.3]
let arr2 = [1.2.3]
print(arr1 == arr2)
// Compare dictionaries whose value is Int
let dic1 = ["age": 19."score": 60]
let dic2 = ["age": 19."score": 60]
print(dic1 == dic2)
/ / is Int?
let age1 = dic1["age"]
let age2 = dic2["age"]
print(age1 == age2)
/// all the above output results are: true
Copy the code
So here if we replace all the ints with ints, right? Swift4.0 cannot compile the Swift4.0 type as follows:
// An array of type Int
let arr1: [Int?] = [1.2.3]
let arr2: [Int?] = [1.2.3]
print(arr1 == arr2)
// Compare dictionaries whose value is Int
let dic1: [String: Int?] = ["age": 19."score": 60]
let dic2: [String: Int?] = ["age": 19."score": 60]
print(dic1 == dic2)
/ / is Int?
let age1 = dic1["age"]
let age2 = dic2["age"]
print(age1 == age2)
Copy the code
- In these cases, we use
= =
Testing equality, in Swift4.0,Int
Type to followEquatable
Protocols, you can compare, butInt?
Types are not followedEquatable
agreement - But in Swift4.1, this problem is solved perfectly, the above code is much better than that, and all output:
true
- in
Swift, 4.0
In the[Set<Int>]
It’s a direct comparison, but[[Int]]
Can’t. nowSwift, 4.1
,[[Int]]
It can also be compared directly - In general,
Swift, 4.1
theArray
,Dictionary
andOptional
As long as their elements are followedEquatable
andHashable
So they followEquatable
andHashable
syntheticEquatable
和 Hashable
- If the objects are equal, the values of the two objects
hash
The values must be equal - If two objects
hash
Values are equal. These two objects are not necessarily equal. Swift
中Hashable
It must beEquatable
Because the former inherited the latter. inSwift 4
In, if followEquatable
When the agreement is made, we must implement itEquatable
Of the agreement= =
Method,Equatable
The agreement is as follows:
public protocol Equatable {
/// Returns a Boolean value indicating whether two values are equal.
///
/// Equality is the inverse of inequality. For any values `a` and `b`,
/// `a == b` implies that `a ! = b` is `false`.
///
/// - Parameters:
/// - lhs: A value to compare.
/// - rhs: Another value to compare.
public static func == (lhs: Self, rhs: Self) -> Bool
}
Copy the code
In Swift4.0, methods of the Equatable protocol must be implemented
struct Name: Equatable {
var name1 = "name1"
var name2 = "name2"
static func == (lhs: Name, rhs: Name) -> Bool {
return lhs.name1 == rhs.name1 &&
lhs.name2 == rhs.name2
}
}
Copy the code
In Swift 4.1, Equatable can be added without implementing any protocol methods
struct Name: Equatable {
var name1 = "name1"
var name2 = "name2"
}
Copy the code
JSON
Encoding time supportCamel Case
andSnake Case
Conversion between
Swift, 4.0
The introduction of theCodable
But there is a troubling question: ifJSON
The data ofkey
The naming format issnake_case
If so, we have to create our ownCodingKeys
To tell Apple how to convert. inSwift, 4.0
In the- But in the
Swift, 4.1
In, apple toJSONDecoder
An attribute is introducedkeyDecodingStrategy
; The correspondingJSONEncoder
An attribute is introducedkeyEncodingStrategy
. So we don’t have to set the definitionCodingKeys
. Only need todecoding
When thekeyDecodingStrategy
Set to.convertFromSnakeCase
; inencoding
When thekeyEncodingStrategy
Set to.convertToSnakeCase
- Here are the parse forms for arrays/dictionaries/collections respectively
struct Student: Codable, Hashable {
let firstName: String
let averageGrade: Int
}
let cosmin = Student(firstName: "Cosmin", averageGrade: 10)
let george = Student(firstName: "George", averageGrade: 9)
let encoder = JSONEncoder()
// Encode an Array of students
let students = [cosmin, george]
do {
try encoder.encode(students)
} catch {
print("Failed encoding students array: \(error)")}// Encode a Dictionary with student values
let studentsDictionary = ["Cosmin": cosmin, "George": george]
do {
try encoder.encode(studentsDictionary)
} catch {
print("Failed encoding students dictionary: \(error)")}// Encode a Set of students
let studentsSet: Set = [cosmin, george]
do {
try encoder.encode(studentsSet)
} catch {
print("Failed encoding students set: \(error)")}// Encode an Optional Student
let optionalStudent: Student? = cosmin
do {
try encoder.encode(optionalStudent)
} catch {
print("Failed encoding optional student: \(error)")}Copy the code
Hashable Index Types
(Hash index)
Extend the use of key-path expressions in the standard library. Make all index types in the library compliant with Hashable so that [Int], String, and all other standard collections behave the same when using key-path subscripts
let swiftString2 = "one two three"
let charact1 = \String.[swiftString2.startIndex]
print(swiftString2[keyPath: charact1])
let arr = [1.2.3.4]
let value2 = \[Int].[1]
print(arr[keyPath: value2])
// Output result:
o
2
Copy the code
compactMap
The use of the
In Swift 4.0, flatMap is often used to filter nil, and dimensionality reduction is also possible, as described in the advanced usage of Swift functional programming
Let arr = [1, 2, nil, 3, 4, nil] let arr1 = arr.flatMap({$0}) print(arr1) Please use compactMap(_:) for the case where closure returns an optional value Use 'compactMap(_:)' instead Let arr = [1, 2, nil, 3, 4, nil] let arr2 = arr.compactMap({$0}) print(arr2)Copy the code
Because flatMap has many overloads in Swift4.0, which may cause ambiguity, flatMap is renamed to compactMap in Swift4.1
Except weak and unowned in the agreement.
- When you are in
Tune
Two attributes are defined in the protocolkey
andpitch
.pitch
May benil
So you can use it in the agreementweak
modified - But if it’s defined in the protocol itself,
weak
andunowned
None of them have any real meaning, so inSwift4.1
These keywords have been removed from the protocol, and use of these keywords in the protocol will trigger a warning
class Key {}
class Pitch {}
// Swift 4
protocol Tune {
unowned var key: Key { get set }
weak var pitch: Pitch? { get set }
}
/ / Swift, 4.1
protocol Tune {
var key: Key { get set }
var pitch: Pitch? { get set }
}
Copy the code
UnsafeMutableBufferPointer
The change of
/ / Swift4.0
let buffer = UnsafeMutableBufferPointer<Int>(start: UnsafeMutablePointer<Int>.allocate(capacity: 10),
count: 10)
let mutableBuffer = UnsafeMutableBufferPointer(start: UnsafeMutablePointer(mutating: buffer.baseAddress),
count: buffer.count)
/ / Swift4.1
let buffer = UnsafeMutableBufferPointer<Int>.allocate(capacity: 10)
let mutableBuffer = UnsafeMutableBufferPointer(mutating: UnsafeBufferPointer(buffer))
Copy the code
Compared to Swift4.0, the key value change of Swift4.1 is too small. It is rumored that the API of Swift5 will be stable, but it is estimated that the change will be very large.
Reference documentation
- What’s New in Swift 4.1?