New in Swift 4.1

  • Apple officially released the official version of 3.29 Xcode 9.3and Swift 4.1, let's see Swift 4.1what new features and new highlights are brought
  • Xcode9.3 is required for testing, please make sure your Xcode is the latest version 9.3
  • Swift 4.1is Swift 4.0source code compatible , so new features won't break your code if you're already using migrating Xcodeyour Swift Migratorproject toSwift 4.0
  • Xcode9.3Next , create a new Playgroundproject and test our code

Conditional Conformance

  • Conditional conformance Protocol conformance for generic types whose type parameters satisfy certain conditions [SE-0143]
  • EquatableIn Swift 4 , you can compare between arrays, between dictionaries, and between optionals if the element types of arrays, dictionaries, or optionals conform , as in the following example:
// Int类型的数组
let arr1 = [1, 2, 3]
let arr2 = [1, 2, 3]
print(arr1 == arr2)

// 比较value值为Int的字典
let dic1 = ["age": 19, "score": 60]
let dic2 = ["age": 19, "score": 60]
print(dic1 == dic2)

// 比较Int?
let age1 = dic1["age"]
let age2 = dic2["age"]
print(age1 == age2)

/// 以上输出结果都是: true

Here, if we change Intall to Int?types, it Swift4.0will not compile in , as follows:

// Int类型的数组
let arr1: [Int?] = [1, 2, 3]
let arr2: [Int?] = [1, 2, 3]
print(arr1 == arr2)

// 比较value值为Int的字典
let dic1: [String: Int?] = ["age": 19, "score": 60]
let dic2: [String: Int?] = ["age": 19, "score": 60]
print(dic1 == dic2)

// 比较Int?
let age1 = dic1["age"]
let age2 = dic2["age"]
print(age1 == age2)
  • In these instances, we use ==test equality, in Swift 4.0, Inttypes follow the Equatableprotocol and can be compared, but the Int?types do not follow the Equatableprotocol
  • But in Swift4.1, this problem is perfectly solved, the above code has passed, and all output:true
  • A direct comparison can be made between the two, but Swift 4.0not . Now , it is also possible to directly compare[Set<Int>][[Int]]Swift 4.1[[Int]]
  • In general, Swift 4.1of Array, Dictionaryand Optional, as long as their elements follow Equatableand Hashable, then they also follow EquatableandHashable

synthetic EquatableandHashable

  • If the objects are equal, the hashvalues must be equal
  • If two objects are equal in hashvalue , the two objects are not necessarily equal.
  • SwiftHashableIt must be Equatable, because the former inherits the latter.
    In Swift 4, if we follow the Equatableprotocol, we must implement Equatablethe ==methods of the protocol, the Equatableprotocol 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
}

In Swift 4.0, Equatablethe methods of the 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
    }
}

In Swift 4.1, only need to add Equatable, no need to implement any protocol method

struct Name: Equatable {
    var name1 = "name1"
    var name2 = "name2"

}

JSONSupports conversion between Camel Caseand when encodingSnake Case

  • Swift 4.0Introduced Codable, but with a nasty problem: if JSONthe keynaming format of snake_casethe data is, we have to create our own CodingKeysto tell Apple how to convert it. in Swift 4.0_
  • But in Swift 4.1, Apple JSONDecoderintroduced an attribute keyDecodingStrategy; correspondingly JSONEncoderintroduced an attribute keyEncodingStrategy. This way we don't need to set CodingKeysthe definition. Just need decodingto keyDecodingStrategyset it to .convertFromSnakeCase; set it encodingtokeyEncodingStrategy.convertToSnakeCase
  • The following is the parsed form for array/dictionary/collection 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)")
}

Hashable Index Types(hash index)

Extends the use of Key-pathexpressions in the standard library. Make all index types in the standard library conform to the Hashableprotocol , so that , [Int], Stringand all other standard key-pathcollections behave the same when subscripting

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])

//输出结果:
o
2

compactMapusage

In Swift 4.0, we often use flatMapit to filter nil, and we can also perform dimensionality reduction operations. For details, please refer to the advanced usage of Swift functional programming.

let arr = [1, 2, nil, 3, 4, nil]
let arr1 = arr.flatMap({ $0 })
print(arr1)

//这样使用会有类似的警告
'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value 
Use 'compactMap(_:)' instead

//Swift4.1中的用法
let arr = [1, 2, nil, 3, 4, nil]
let arr2 = arr.compactMap({ $0 })
print(arr2)

Mainly because there Swift4.0are flatMapmany overloads in , which may cause ambiguity, so rename it Swift4.1toflatMapcompactMap

Except for weak and unowned in the protocol.

  • When you Tunedefine two properties keyand in the protocol pitch, it pitchmay be nil, so you can weakdecorate the protocol with
  • But if they are defined in the protocol itself, weakand unownedhave no practical significance, so Swift4.1these keywords have been removed in the protocol, and the use of these keywords in the protocol will cause 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 }
}

UnsafeMutableBufferPointerchange

//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))

Relative Swift4.0changes, Swift4.1this change of the key value is too trivial, the legend Swift5will APItend to be stable, but it is estimated that the change may be very large, waiting for the Swift5release...

Reference documentation

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324812657&siteId=291194637