• No se han encontrado resultados

Proceso de implantación del programa

3.1. Área de coordinación institucional

This section shows some of the functions from the Kotlin standard library for working with collections. Along the way, it describes a few related language features:

Thevararg keyword, which allows you to declare a function taking an arbitrary number of arguments

An infix notation that lets you call some one-argument functions without ceremony Destructuring declarations that allow you to unpack a single composite value into multiple variables

3.4.1 Extending the Java Collections API

We started this chapter with the idea that collections in Kotlin are the same classes as in Java, but with an extended API. You saw examples of getting the last element in a list and finding the maximum in a collection of numbers:

We were interested in how it works: why it’s possible to do so many things with collections in Kotlin while using the Java library classes. Now the answer should be clear: thelastandmaxfunctions are declared as extension functions!

The last function is no more complex than lastChar forString, discussed in the previous section: it’s an extension on theList class. For max, let’s look at a simplified declaration. The real library function works not only for

comparable elements:

Int numbers, but for any

fun <T> List<T>.last(): T { /* returns the last element */ }

fun Collection<Int>.max(): Int { /* finding a maximum in a collection */ }

Many extension functions are declared in the Kotlin standard library, and we won’t list all of them here. You may wonder about the best way to learn everything in the Kotlin standard library. You don’t have to—any time you need to do something with a collection or any other object, the code completion in the IDE will show you all the possible functions available for that type of object. The list includes both regular methods and extension functions; you can choose the function you need.

At the beginning of the chapter, you also saw the functions for creating collections. A common trait of those functions is that they can be called with an arbitrary number of arguments. In the following section, you’ll see the syntax for declaring such functions.

>>> val strings: List<String> = listOf("first", "second", "fourteenth")

>>> strings.last() fourteenth

>>> val numbers: Collection<Int> = setOf(1, 14, 2)

>>> numbers.max() 14

3.4.2 Varargs: functions that accept an arbitrary number of arguments

When you call a function to create a list, you can pass any number of arguments to it:

If you look up how this function is declared in the library, you’ll find the following:

You’re probably familiar with Java’s varargs: a feature that allows you to pass an arbitrary number of values to a method by packing them in an array. Kotlin’s varargs are similar to those in Java, but the syntax is slightly different: instead of three dots after the type, it uses thevararg modifier on the parameter.

One other difference between Kotlin and Java is the syntax of calling the function when the arguments you need to pass are already packed in an array. In Java, you pass the array as is, whereas Kotlin requires you to explicitly unpack the array. Technically, this feature is called using a spread operator, but in practice it’s as simple as putting the

*character before the corresponding argument:

Spread operator unpacks the array contents

The spread operator lets you combine the values from an array and some fixed values in a single call. This isn’t supported in Java.

Now let’s move on and start talking about maps. We’ll briefly discuss another way to improve the readability of Kotlin function invocations: the infix call.

3.4.3 Working with pairs: infix calls and destructuring declarations

To create maps, you use themapOf() function:

This is a good time to provide another explanation we promised you at the beginning of the chapter. The word to in this line of code isn’t a built-in construct, but rather a method invocation of a special kind, called an infix call.

In an infix call, the method name is placed immediately between the target object name and the parameter, with no extra separators. The following two calls are equivalent:

val list = listOf(2, 3, 5, 7, 11)

fun listOf<T>(vararg values: T): List<T> { ... }

fun main(args: Array<String>) { val list = listOf("args: ", *args) println(list)

}

val map = mapOf(1 to "one", 7 to "seven", 53 to "fifty-three")

1.to("one") 1 to "one"

Calls the to function in the regular way Calls the to function using an infix notation

Infix calls can be used with regular methods and extension functions that have one required parameter. To allow a function to be called using the infix notation, you need to mark it with theinfix modifier. Here’s a simplified version of the declaration of the to function:

The to function returns an instance of Pair, which is a Kotlin standard library class that, unsurprisingly, represents a pair of elements. The actual declarations ofPair andto

use generics, but we’re omitting them here to keep things simple.

Note that you can assign a pair of elements to two variables directly:

This feature is called a destructuring declaration. Figure 3.3 illustrates how it works with pairs.

Figure 3.3 You create a pair using the to function and unpack it with a destructuring declaration.

The destructuring declaration feature isn’t limited to pairs. For example, you can assign a map entry to two separate variables,keyandvalue, as well.

This also works with loops, as you’ve seen in the implementation of

joinToString(), which uses the withIndex() function:

infix fun Any.to(other: Any) = Pair(this, other)

val (number, name) = 1 to "one"

for ((index, element) in collection.withIndex()) { println("$index: $element")

}

The section 7.4 will describe when it’s possible to destructure an expression and assign it to several variables.

Theto function is an extension function. You can create a pair of any elements, which means it’s an extension to a generic receiver: you can write1 to "one","one"

to 1,list to list.size(), and so one.

Let’s look at the declaration of themapOffunction:

Like listOf, mapOf accepts a variable number of arguments, but this time they should be pairs of keys and values.

Even though the creation of a new map may look like a special construct in Kotlin, it’s a regular function with a concise syntax. Next, let’s discuss how extensions simplify dealing with strings and regular expressions.