官术网_书友最值得收藏!

How it works...

Let's take a look at the different types of closures we just implemented:

// No input, no output 
let printAuthorsDetails: () -> Void = {
let name = PersonName(givenName: "Keith", middleName: "David", familyName: "Moon")
let author = Person(name: name)
print(author.displayString)
}

As a first-class type in Swift, closures can be assigned to constants or variables, and constants and variables need a type. To define a closure's type, we need to specify the input parameter types and the output type, and for the closure in the preceding code, the type is () -> Void. The Void type is another way of saying nothing, so this closure takes no inputs and returns nothing, and the closure's functionality is defined within the curly brackets, as with other functions.

Now that we have this closure defined and assigned to the printAuthorsDetails constant, we can execute it as follows, which will cause this author's details to be printed:

printAuthorsDetails() // "Keith David Moon - Location: UK" 

The next closure type takes no input parameters, but returns a Person object, as you can see with the () -> Person type definition:

// No input, Person output 
let createAuthor: () -> Person = {
let name = PersonName(givenName: "Keith", middleName: "David", familyName: "Moon")
let author = Person(name: name)
return author
}
let author: Person = createAuthor()
print(author.displayString) // "Keith David Moon - Location: UK"

Since it has an output, the execution of the closure returns a value and can be assigned to a variable or constant. In the preceding code, we execute the createAuthor closure and assign the output to the author constant. Since we defined the closure type as () -> Person, the compiler knows that the output type is a Person and therefore the type of the constant can be inferred, so we don't need to explicitly declare it. Let's remove the explicit type declaration:

let author = createAuthor() 
print(author.displayString) // "Keith David Moon - Location: UK"

Next, let's take a look at a closure that takes input parameters:

// String inputs, no output 
let printPersonsDetails: (String, String, String) -> Void = { given, middle, family in
let name = PersonName(givenName: given, middleName: middle, familyName: family)
let author = Person(name: name)
print(author.displayString)
}
printPersonsDetails("Kathleen", "Mary", "Moon") // "Kathleen Mary Moon - Location: UK"

You will remember, from the recipe on functions, that we can define parameter labels, which define how the parameters are referenced when the function is used, and parameter names, which define how the parameter is referenced from within the function. In closures, these are defined a bit differently:

  • Parameter labels cannot be defined for closures, so, when calling a closure, the order and parameter type have to be used to determine what values should be provided as parameters:
(String, String, String) -> Void 
  • Parameter names are defined inside the curly brackets, followed by the in keyword:
given, middle, family in 

Putting it all together, we can define and execute a closure with inputs and an output, as follows:

// String inputs, Person output 
let createPerson: (String, String, String) -> Person = { given, middle, family in
let name = PersonName(givenName: given, middleName: middle, familyName: family)
let person = Person(name: name)
return person
}
let melody = createPerson("Melody", "Margaret", "Moon")
print(melody.displayString) // "Melody Margaret Moon - Location: UK"
主站蜘蛛池模板: 虞城县| 泸溪县| 绵竹市| 大港区| 新余市| 洞口县| 沅江市| 沙坪坝区| 石柱| 滦南县| 霸州市| 托克逊县| 铜川市| 盐池县| 嘉义县| 黄平县| 马尔康县| 聂拉木县| 阿拉善盟| 津南区| 郓城县| 永泰县| 汽车| 西青区| 固始县| 乌苏市| 六枝特区| 丰顺县| 呼和浩特市| 华亭县| 饶河县| 碌曲县| 建德市| 梅州市| 甘德县| 襄城县| 礼泉县| 博客| 含山县| 普安县| 丰台区|