A brief introduction to Such an interface can be seen in the Swift 5.6 update list, but such simplicity leads to confusion. After some verification, here is my understanding of the change. SE-0335

For example, the paper

Typically, protocols are used to ensure type consistency and comply with requirements such as implementing a method:

protocol ProtocolA {
    func test(a)
}

struct Test: ProtocolA {
    func test(a) {
        print("hello")}}let t = Test()
t.test() /// Static Dispatch
Copy the code

When t is of unambiguous type, Swift uses Static Dispatch for t.test() calls, which is more efficient.

If we want to call the test method because we don’t know the type in some cases (and we do), we’ll write it like this:

let t: ProtocolA = Test()
t.test() /// Dynamic Dispatch
Copy the code

In this case, the type of T can be called Existential Type. Swift uses Dynamic Dispatch to complete the test call. The current scenario is a V-Table call, which is less efficient than static Dispatch.

So the any keyword is added to HANDLE the Case of An Existential Type in SE-0335, which should read in 5.6:

let t: any ProtocolA = Test()
t.test() /// Static Dispatch
Copy the code

At this point it will go static distribution.

Further examples

In case you think this scenario is rare, let me give you two more examples

Example 1

struct A {
    var obs: [ProtocolA]?
}

let a = A()
a.obs?.map {
    /// dynamic dispatch
    $0.test()
}

struct B {
    /// Introduce the any keyword
    var obs: [any ProtocolA]?
}

let b = B()
b.obs?.map {
    /// static dispatch
    $0.test()
}
Copy the code

It can be seen that the above scenario is often encountered in daily development. In the original writing method, each OB is distributed dynamically, but after the introduction of any keyword, it becomes static distribution, which improves efficiency.

Example 2

The second scenario is the confusion I encountered while writing the basic components. Take a look at the code first:

func test1(obj: ProtocolA) {
    obj.test()
}

func test2<T: ProtocolA> (obj: T) {
    obj.test() 
}
Copy the code

I was confused about the difference between the two, because at compile level there is no difference (you can specify the type when a method uses generics as its return value). Test1 (any); test2 (any); test2 (any);

func test(obj: any ProtocolA) {
    obj.test() /// Static Dispatch
}
Copy the code

The above.

The latter

This feature is currently available in Xcode 13.3. For this feature, Apple plans to warn where it is involved in a future Swift 5.x release and throw an error directly from Swift 6.

This change has the potential to break existing code in the future, so use the correct form as much as possible during the transition. In my opinion, this change is very important, and the process of understanding can also deepen the understanding of the Protocol type.