- Apple officially released the official version of 3.29
Xcode 9.3
andSwift 4.1
, let's seeSwift 4.1
what 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.1
isSwift 4.0
source code compatible , so new features won't break your code if you're already using migratingXcode
yourSwift Migrator
project toSwift 4.0
Xcode9.3
Next , create a newPlayground
project and test our code
Conditional Conformance
- Conditional conformance Protocol conformance for generic types whose type parameters satisfy certain conditions [SE-0143]
Equatable
In 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 Int
all to Int?
types, it Swift4.0
will 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,Int
types follow theEquatable
protocol and can be compared, but theInt?
types do not follow theEquatable
protocol - 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.0
not . Now , it is also possible to directly compare[Set<Int>]
[[Int]]
Swift 4.1
[[Int]]
- In general,
Swift 4.1
ofArray
,Dictionary
andOptional
, as long as their elements followEquatable
andHashable
, then they also followEquatable
andHashable
synthetic Equatable
andHashable
- If the objects are equal, the
hash
values must be equal - If two objects are equal in
hash
value , the two objects are not necessarily equal. Swift
Hashable
It must beEquatable
, because the former inherits the latter.
InSwift 4
, if we follow theEquatable
protocol, we must implementEquatable
the==
methods of the protocol, theEquatable
protocol 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, Equatable
the 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"
}
JSON
Supports conversion between Camel Case
and when encodingSnake Case
Swift 4.0
IntroducedCodable
, but with a nasty problem: ifJSON
thekey
naming format ofsnake_case
the data is, we have to create our ownCodingKeys
to tell Apple how to convert it. inSwift 4.0
_- But in
Swift 4.1
, AppleJSONDecoder
introduced an attributekeyDecodingStrategy
; correspondinglyJSONEncoder
introduced an attributekeyEncodingStrategy
. This way we don't need to setCodingKeys
the definition. Just needdecoding
tokeyDecodingStrategy
set it to.convertFromSnakeCase
; set itencoding
tokeyEncodingStrategy
.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-path
expressions in the standard library. Make all index types in the standard library conform to the Hashable
protocol , so that , [Int]
, String
and all other standard key-path
collections 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
compactMap
usage
In Swift 4.0
, we often use flatMap
it 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.0
areflatMap
many overloads in , which may cause ambiguity, so rename itSwift4.1
toflatMap
compactMap
Except for weak and unowned in the protocol.
- When you
Tune
define two propertieskey
and in the protocolpitch
, itpitch
may benil
, so you canweak
decorate the protocol with - But if they are defined in the protocol itself,
weak
andunowned
have no practical significance, soSwift4.1
these 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 }
}
UnsafeMutableBufferPointer
change
//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.0
changes,Swift4.1
this change of the key value is too trivial, the legendSwift5
willAPI
tend to be stable, but it is estimated that the change may be very large, waiting for theSwift5
release...