Entradas

Mostrando entradas de abril, 2019

Ejemplos de función anónima y lambda para crear un Array

Imagen
Vamos a ver un ejemplo sencillo para ilustrar la entrada Funciones de orden superior, anónimas y lambdas y concretamente el uso de una función anónima y una lambda . Con este pequeño ejemplo vamos a intentar demostrar que realmente las expresiones lambda son una forma simplificada de pasar una funcionalidad como parámetro sin la necesidad de crear funciones anónimas, lo cual es una ventaja al requerir menos código, lo que facilita su legibilidad. El objetivo del ejercicio es crear un array de los diez primeros números pares. Una primera aproximación podría ser: fun main ( args : Array < String >) {                val arrayPares = IntArray ( 10 ) // también: arrayOfNulls<Int>(10)            for ( i in arrayPares . indices ) {         arrayPares [ i ] = ( i + 1 ) * 2     }           for ( numero in arrayPares ) { // recorremos el array                print ( " $numero " ) // 2 4 6 8 10 12 14 16 18 20     }     } Otra opción para c

Funciones de orden superior, anónimas y lambdas

Imagen
En Kotlin se puede operar con las funciones al igual que se opera con otros valores que no son funciones: las funciones pueden almacenarse en variables y estructuras de datos, pasarse como argumentos y devolverse desde otras funciones de orden superior. Para facilitar esto, Kotlin utiliza un tipo específico de función para representar funciones y proporciona unas construcciones especializadas como las expresiones lambda. En esta entrada vamos a hacer una primera aproximación introductoria a las funciones de orden superior, anónimas y lambdas. Funciones de orden superior Las funciones de orden superior permiten tratar a las funciones como cualquier otro valor y por tanto pueden recibir como parámetros otras funciones y/o devolverlas como resultado. Un ejemplo: fun calcular ( n1 : Int , n2 : Int , operacion : ( Int , Int ) -> Int ): Int {     return operacion ( n1 , n2 ) } fun sumar ( x : Int , y : Int ) = x + y fun restar ( x : Int , y : Int ) = x

I/O: entrada y salida de datos en consola

Imagen
Dentro de la biblioteca estándar de Kotlin, el paquete kotlin.io proporciona elementos esenciales para trabajar con los flujos de entrada y salida estándar ( Input/Output o I/O). Esta transmisión de información entre la memoria principal y los dispositivos de entrada y salida permite, entre otras cosas, leer y escribir datos. En esta entrada vamos a tratar sobre cómo se transfieren datos de entrada y salida en consola (el paquete kotlin.io también proporciona herramientas para trabajar con archivos, como veremos en futuras entradas), lo que es útil para mostrar una información en pantalla y para obtener información aportada por el usuario, habitualmente a través de un dispositivo de entrada como el teclado . Output : Escribir en consola Como ya hemos visto en multitud de ejemplos previos, para enviar un mensaje a la salida estándar (la pantalla) usamos habitualmente las funciones print() y println() , que se diferencian en que la segunda incluye un salto de línea al final

Comprobación y conversión de tipos con is y as

Imagen
Cuando vimos los tipos básicos de datos , ya adelantamos algunas cuestiones básicas sobre la comprobación y conversión de tipos en Kotlin, y ahora vamos a recordarlas y profundizar en ellas. Con el operador is (y con su negación !is ) podemos verificar si un objeto se ajusta a un determinado tipo (en el siguiente ejemplo, utilizando el supertipo Any estamos diciendo que puede ser de cualquier tipo no anulable): val obj1 : Any = "¿Soy un String?" if ( obj1 is String ) {     println ( obj1 . length ) } val obj2 : Any = 2 if ( obj2 ! is String ) { // if !(obj2 is String)     println ( "No es un String" ) } else {     println ( obj2 . length ) } Es posible que hayas pasado por alto que en el ejemplo anterior se ha producido una conversión implícita de tipos, y es que en ocasiones en Kotlin no es necesario usar operadores de conversión explícitos porque el compilador realiza un seguimiento y comprobación de los tipos y automáticamente in

Programa para obtener los números primos en un intervalo

Imagen
El siguiente programa ilustra los contenidos expuestos en las entradas referentes a las estructuras de repetición (bucles con for y while ), a las funciones y al uso de break para escapar de un bucle. Objetivo: Obtener y mostrar todos los números primos existentes entre dos números enteros. Solución: fun main ( args : Array < String >) { var menor = 20 // observa la diferencia entre var y val val mayor = 50 print ( "Números primos entre $menor y $mayor : " ) while ( menor < mayor ) { // bucle para revisar el intervalo entre los números if ( checkPrimo ( menor )) // evalúa el retorno de la función con cada valor print ( menor . toString () + " " ) ++ menor // actualiza el valor } } fun checkPrimo ( num : Int ): Boolean { // función que retorna un booleano var primo = true for ( i in 2 .. num / 2 ) { // bucle sobre un rango if ( num %

Introducción a las funciones en Kotlin

Imagen
En programación una función es un procedimiento o subrutina que realiza una tarea específica y puede retornar un valor. Las funciones pueden tomar parámetros que modifican su funcionamiento y son utilizadas para descomponer problemas mayores en tareas simples y para implementar operaciones que son recurrentemente utilizadas durante un programa y de esta manera reducir la cantidad de código y conseguir un código más eficiente. Las funciones en Kotlin son declaradas usando la palabra fun seguida por un identificador,  luego los parámetros y su tipo (si existen) y el tipo de dato que devuelve (si existe) y finalmente el bloque de instrucciones que se ejecuta entre llaves que terminará con la instrucción return en caso de que devuelva algún valor. Las funciones son llamadas o invocadas con su nombre seguido de los argumentos entre paréntesis (si existen). Cuando una función no devuelve ningún valor, el tipo de retorno es Unit , y entonces no se requiere explicitarlo. Unos ejemplo

Escapar del bucle con break y continue

Imagen
Hasta ahora hemos visto estructuras condicionales y repetitivas para controlar el flujo de un programa, pero otra forma de gestionar la secuencia de un programa es través de saltos o interrupciones de ciertos bloques de código. Kotlin tiene tres expresiones principales para romper la estructura secuencial de un programa provocando saltos en la estructura del código : return : en general sale de una función y retorna un valor. break :  detiene la ejecución de un bucle y sale de él, por lo que no se ejecuta el código que se encuentre después en el cuerpo de ese bucle. continue : interrumpe una iteración dentro de un bucle (normalmente en base a una condición específica), y vuelve al principio del bucle para realizar otra iteración, si corresponde. Ahora nos vamos a centrar en las dos últimas expresiones y en su uso en los bucles , y dejaremos return para cuando veamos las funciones. Por ejemplo, podemos detener un bucle en base a una condición: for ( i in 1 . .10 ) {

Bucles o estructuras de repetición II: while

Imagen
Siguiendo la serie sobre estructuras de repetición (ver Bucles o estructuras de repetición I: for ), while es otra instrucción que permite controlar el flujo de un programa mediante bucles o ciclos repetitivos. La sintaxis de while es: while ( expresión evaluada ) {     // cuerpo del bucle } Donde la expresión evaluada o condición entre paréntesis es una expresión booleana, que si es evaluada como verdadera da lugar a la ejecución de las sentencias del cuerpo del bucle y luego se vuelve a revaluar la expresión, y este proceso continúa en bucle hasta que la expresión es considerada falsa (para evitar escribir bucles infinitos no deseados necesitamos que dentro del bucle se actualice el valor que usemos en la expresión evaluada). Algunos ejemplos: // imprime del 5 al 1 var x = 5     while ( x > 0 ) {   // true mientras x es mayor que 0     println ( x --) } // imprime 5 líneas (o una línea 5 veces) var i = 1 while ( i <= 5 ) { // true mientras i es me

Programa para obtener los factores de un número

Imagen
Para apoyar el contenido de la entrada Bucles o estructuras de repetición I: for , se expone como ejemplo un programa que utiliza for para iterar sobre un rango y sobre una lista. Objetivo: Obtener y mostrar todos los factores de un número positivo determinado. Recuerda que los factores de un número son aquellos números cuyo producto dan como resultado ese número, o dicho de otro modo, son los términos en que se puede descomponer multiplicativamente ese número; y que podemos obtener los factores de un número comprobando si ese número es divisible por todos y cada uno de los números que hay desde el 1 hasta ese número. Solución: fun main ( args : Array < String >) { val numero = 72 val listaFactores : MutableList < Int > = mutableListOf () // lista para guardar los factores print ( "Los factores de $numero son: " ) for ( i in 1 .. numero ) { // bucle sobre un rango if ( numero % i == 0 ) { // si se c

Bucles o estructuras de repetición I: for

Imagen
Además de las instrucciones condicionales ( if , when ), otras estructuras para controlar el flujo de un programa son las estructuras de repetición , que consisten en una serie de instrucciones para generar bucles , y fundamentalmente son las instrucciones for y while , centrándonos ahora en la primera. for genera un bucle que se repite sobre cualquier objeto que proporciona un iterador, con esta sintaxis (el cuerpo se escribe como un bloque entre llaves cuando ocupa más de una línea): for ( item in collection ) print ( item ) for ( item : Int in ints ) {     // ...     // ... } Por ejemplo: val items = listOf ( "manzana" , "plátano" , "kiwi" ) for ( item in items ) println ( item ) for ( index in items . indices ) {     println ( "En la posición ${index + 1} la fruta es ${items[index]} " ) } Podemos iterar sobre un rango de números con una expresión de rango (para delante y para atrás, y cambiando el paso

Instrucciones condicionales II: when

Imagen
Siguiendo la serie sobre estructuras de selección (ver Instrucciones condicionales I: if ), when es otra estructura condicional especialmente útil en situaciones que, evitando if anidados, tenemos que verificar múltiples condiciones. when comprueba su argumento con cada unas de las ramas de forma secuencial hasta que alguna se cumple y entonces el resto se ignora. Al igual que if , se puede utilizar como una declaración o como una expresión , y en este último caso, devuelve el valor de la rama verificada (y al igual que if , cada rama puede ser un bloque y su valor es el valor de la última expresión del cuerpo del bloque). when utilizado como una declaración: val x = 2 when ( x ) {     1 -> print ( "x == 1" )     2 -> print ( "x == 2" )     else -> { // bloque         print ( "x no es ni 1 ni 2" )     } } La rama else se evalúa si no se satisface ninguna de las otras condiciones. Observa en el ejemplo anterior que se