• Apple released the official version on March 29Xcode 9.3andSwift, 4.1Let’s seeSwift, 4.1What 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.1withSwift, 4.0Is source code compatible, so if you already useXcodeIn theSwift MigratorMigrate your project toSwift, 4.0Then the new feature won’t break your code
  • The following inXcode9.3Let’s go ahead and create a new onePlaygroundEngineering, 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 followsEquatableYou 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,IntType to followEquatableProtocols, you can compare, butInt?Types are not followedEquatableagreement
  • But in Swift4.1, this problem is solved perfectly, the above code is much better than that, and all output:true
  • inSwift, 4.0In 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.1theArray,DictionaryandOptionalAs long as their elements are followedEquatableandHashableSo they followEquatableandHashable

syntheticEquatableHashable

  • If the objects are equal, the values of the two objectshashThe values must be equal
  • If two objectshashValues are equal. These two objects are not necessarily equal.
  • SwiftHashableIt must beEquatableBecause the former inherited the latter. inSwift 4In, if followEquatableWhen the agreement is made, we must implement itEquatableOf the agreement= =Method,EquatableThe 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

JSONEncoding time supportCamel CaseandSnake CaseConversion between

  • Swift, 4.0The introduction of theCodableBut there is a troubling question: ifJSONThe data ofkeyThe naming format issnake_caseIf so, we have to create our ownCodingKeysTo tell Apple how to convert. inSwift, 4.0In the
  • But in theSwift, 4.1In, apple toJSONDecoderAn attribute is introducedkeyDecodingStrategy; The correspondingJSONEncoderAn attribute is introducedkeyEncodingStrategy. So we don’t have to set the definitionCodingKeys. Only need todecodingWhen thekeyDecodingStrategySet to.convertFromSnakeCase; inencodingWhen thekeyEncodingStrategySet 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

compactMapThe 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 inTuneTwo attributes are defined in the protocolkeyandpitch.pitchMay benilSo you can use it in the agreementweakmodified
  • But if it’s defined in the protocol itself,weakandunownedNone of them have any real meaning, so inSwift4.1These 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

UnsafeMutableBufferPointerThe 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?