The original link

More good articles, please pay attention to the public number of knowledge small set (ID: zsxjtip)

Apple officially announced Swift 5.1 in a Swift release on 9.20 LOCAL time. Swift 5.1 extends the stability features of the language beyond Swift 5. But wait, this article is not a compilation of official documentation, but a compilation of Xcode 11 Release Note.

Swift support in Xcode 11 has also been partially updated, including some new features and fixes. We’ll separate out swift-related content here. It mainly consists of Swift language itself and Swift Package. SwiftUI is still being updated, so I won’t mention it here. The Swift compiler doesn’t have many updates.

If there is a problem with the content, please point it out in the comments section, so everyone can see the problem, thanks.

Swift

• You can now use the @frozen property of structures and enumerations.

• The structure’s member initializer provides default values for parameters that contain default expressions.

struct Dog {
    var name = "Generic dog name"
    var age = 0

    // The synthesized memberwise initializer
    init(name: String = "Generic dog name", age: Int = 0)
}

let sparky = Dog(name: "Sparky") // Dog(name: "Sparky", age: 0)
Copy the code

• You can now declare the @Autoclosure parameter using a type alias.

class Foo {
    typealias FooClosure = () -> String
    func fooFunction(closure: @autoclosure FooClosure) {}
}
Copy the code

• Methods declared in classes using the @objc attribute can now return Self.

class MyClass: NSObject {
    @objc func clone() -> Self { return self }
}
Copy the code

• Key path expressions can now contain references to tuple elements.

• Single-argument functions that accept type Any no longer take precedence over other functions.

• Conversions between tuple types are now fully implemented. Previously, the following code was problematic:

let values: (Int, Int) = (10, 15)
letconverted: (Int? , Any) = valuesCopy the code

• Type subscripts can now be declared and used, just like type attributes and type methods. Declare one by applying static or the class modifier in a class to a subscript declaration.

// Declare a type with a static subscript:
enum ProcessEnvironment {
    static subscript(name: String) -> String? {
        get { getenv(name) }
        set { setenv(name, to: newValue) }
    }
}

// Use it with any of these syntaxes:
ProcessEnvironment["PATH"]! + =":/usr/local/bin"
ProcessEnvironment["PATH"]! + =":/usr/local/bin"
someVarOfProcessEnvironmentDotType["PATH"]! + =":/usr/local/bin"
Copy the code

Type subscripts can also be used with dynamic member lookups to create dynamic type attributes.

// Declare a typeWith a static subscript: @dynamicMemberLookup enum ProcessEnvironment {//... As above... static subscript(dynamicMember name: String) -> String? { get { self[name] }set{ self[name] = newValue } } } // Now you can use property syntax with ProcessEnvironment: ProcessEnvironment.PATH! + =":/usr/local/bin"ProcessEnvironment.self.PATH! + =":/usr/local/bin"someVarOfProcessEnvironmentDotType.PATH! + =":/usr/local/bin"
Copy the code

• Assigning optional. none to an enumeration with None, or comparing such an enumeration with optional. none, now generates a warning. Such expressions are ambiguous because the compiler selects optional. none instead of The None case defined by your own enumeration.

enum Foo { case none }

// Assigned Optional.none instead of Foo.none.
let foo: Foo? = .none
// Comparing with Optional.none instead of Foo.none.
let isEqual = foo == .none
Copy the code

The compiler provides warnings as well as fix-it, replacing.none with optional. none or foo. none to resolve ambiguity.

• Functions can now hide their specific return type by declaring the protocol it conforms to, rather than specifying the exact return type:

func makeACollection() -> some Collection {
    return[1, 2, 3]}Copy the code

The code calling this function can use the protocol’s interface, but cannot see the underlying type.

• Enum cases can now match optional enumerations without requiring “? “at the end of a pattern. .

enum Foo { case zero, one }

let foo: Foo? = .zero

switch foo {
    case .zero: break
    case .one: break
    case .none: break
}
Copy the code

• The existing @dynamicMemberLookup property now supports the typed key Path implementation.

struct Point {
    var x, y: Int
}

@dynamicMemberLookup
struct Box<T> {
    var v: T

    init(_ v: T) {
        self.v = v
    }

    subscript<U>(dynamicMember member: KeyPath<T, U>) -> U {
        get { return v[keyPath: member] }
    }
}

var box = Box(Point(x: 0, y: 0))
_ = box.x
Copy the code

• You can now use Self expressions to reference structures, enumerations, and classes to declare their own types. For example, the two method declarations in this structure are equivalent:

struct Box<Value> {
    func transform1() -> Self { return self }
    func transform2() -> Box<Value> { return self }
}
Copy the code

In a class, Self is the dynamic type of the value Self, as before. The existing restrictions on Self in the declaration type still apply; That is, Self can only appear as the return type of a method. However, Self can now be used within the method body without limitation.

Array and ContiguousArray now have init (unsafeUninitializedCapacity: initializingWith:) initialization program, it provides access to uninitialized memory Array.

• More thorough checks have been made on the limitations of escaping closures that capture in-out parameters or noescape type values. While most code is unaffected, there are edge cases where the Swift 5.0 compiler accepts code that violates these restrictions.

An example of invalid code incorrectly accepted by the Swift 5.0 compiler is the @escaping closure, which calls a local function that references an in-out argument to an external scope:

struct BadCaptureExample {
    var escapingClosure: () -> ()

    mutating func takesInOut(_ x: inout Int) {
        func localFunction() {
            x += 1
        }

        escapingClosure = { localFunction() }
    }
}
Copy the code

The compiler now correctly diagnoses the above code by indicating that localFunction() is not capturing x, because localFunction() is referenced from the @escaping closure.

This also solves problems where the compiler mistakenly diagnoses some code as invalid when no limitation violation has actually occurred. Such as:

func takesNoEscape(_ fn: () -> ()) {
    func localFunction() {
        fn()
    }

    { localFunction() }()
}
Copy the code

Resolved problems

• Duplicate tuple element tags are no longer allowed, as it causes incorrect behavior.

The following are now diagnosed as errors:

let dupLabels: (foo: Int, foo: Int) = (foo: 1, foo: 2)
enum Foo {
    case bar(x: Int, x: Int)
}
let f: Foo = .bar(x: 0, x: 1)
Copy the code

You can still use duplicate labels when declaring functions and subscripts, as long as the internal labels are different. Such as:

func foo(bar x: Int, bar y: Int) {}
subscript(a x: Int, a y: Int) -> Int {}
Copy the code

• Static libraries are now always fully forced to load during linking, fixing most “Unable to demangle” runtime errors.

• Weak and unowned storage attributes no longer affect automatic composition of Equatable or Hashable consistency.

• If symbols in the crash log are not decoded correctly, run swift-demangle and pass in the contents of the crash log.

• Importing a module from the module interface works fine if the type has the same name as the module it contains.

Swift Packages

• Xcode now supports creating and using Swift Packages, as well as adding, removing, and managing package dependencies. Package management in Xcode supports projects built on top of the open source Swift Package Manager project.

Solved problem

• Code Completion applies to the Swift Package target regardless of whether the target name declared in the package. swift manifest file is the same in case as the directory name for that target.

• Adding a new file to the C series target of the Swift package does not create a file with the.swift extension.

• Swift Packages set using unsafeFlags build Settings cannot be used as dependencies.