Why Apple's closure declarations missing argument labels

一世执手 提交于 2019-12-08 00:05:23

问题


As I read through the UIKit, most of the time I see closures (as a function parameter) with missing argument labels like this: func fooClosure(fooClosure: (Bool) -> Swift.Void)

In some cases I can guess what it stands for, in others I can't.

Example:

Take a look at one of UIActivityViewController's closure (as a type alias):

public typealias UIActivityViewControllerCompletionWithItemsHandler = (UIActivityType?, Bool, [Any]?, Error?) -> Swift.Void

What does 3rd type stand for? I have to look at the Objective-C version of the code to know these are returnedItems.

Why it is not implemented that way: (note the activityItems label)

public typealias UIActivityViewControllerCompletionWithItemsHandler = (UIActivityType?, Bool, _ activityItems: [Any]?, Error?) -> Swift.Void

Edit: - Is this just a temporary state (since the Swift is not fully integrated in these frameworks yet)? Code is less readable without argument labels.


回答1:


The problem is that this is a function signature typealias generated by machine, and the machine isn't doing what you would like it to do. Consider the following Objective-C declaration:

typedef void (^MyCoolType)(NSString* __nullable name);

The Swift generated interface for that is:

public typealias MyCoolType = (String?) -> Swift.Void

As you can see, name got stripped out; it is nowhere to be seen.

Nothing stops you from defining a function signature typealias with internal labels, in Swift. This is legal:

public typealias MyCoolType = (_ name:String?) -> Void

But that does not happen to be how the generated interface is generated from Objective-C.




回答2:


As of Swift 3, keywords are no longer a part of a closure's type, thus they don't (and can't) appear anywhere a type is expected, such as in type alias and func declarations.

See the answer in this post for more information.




回答3:


Closures are designed to be versatile. You don't have parameter names because the function you create to pass in could be wildly different from the function someone else rights.

Remember, the parameter names belong to the function.

To illustrate, when I create a function, I would do it like this:

func getUser(for name: String) -> User {
    // Stuff here...
}

I add the label so myself and others know how to properly use the function.

A closure parameter is not a function, you pass in a function. The function one person writes could create a cheese burger, while another person could write one that rotates a view 180º and segue to a new view controller.

With an example from Apples Documentation on UIView, there is an ending closure called completion. As this name suggests, this function is fired when the animation completes. Now the docs do explain that the Bool value tells you whether the animation is complete or not, something that is not obvious from the function itself.

If your not sure what the parameter is used for (example being above), look at the docs.

Hope this answers your question.



来源:https://stackoverflow.com/questions/41514014/why-apples-closure-declarations-missing-argument-labels

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!