Está en la página 1de 12
Algoritmos y Estructura de Datos Departamento de Ingenieria en Sistemas de Informacién Universidad Tecnolégica Nacional FRBA Ing.Roxana Leituz 18/10/2018 Material introductorio lenguaje Go ~ Cétedra a cargo del Dr. O. Bruno Que es GO? Go es un lenguaje de programacién inspirado en C, compilado, estéticamente tipado, concurrente. Podemos decir que “nacid” en el afio 2009 y esté siendo utilizado por empresas como Docker, UBER, entre otros. Los disefiadores de este lenguaje son: Rob Pike y Ken Tompson. Go fue construido para ser utilizado como un lenguaje orientado a software de sistemas (es decir, sistemas operativos, drivers de dispositivos), lo cual animé a desarrolladores de C y C+. Segiin el equipo de Go, los desarrolladores de aplicaciones, y no los desarrolladores de software de sistemas, se han convertido en los principales usuarios de Go. no existen dependencias a la hora de ejecutar programas compilados con Go. No hay que preocuparse sobre si los usuarios tienen Ruby 0 la JVM instalada o, sila tienen, qué version tendrén. Por este motivo Go se esta convirtiendo en un lenguaje popular con el que desarrollar aplicaciones de linea de comandos u otro tipo de programas de utilidades que necesiten ser distribuibles. https://github.com/golang/go/wiki/GoUsers. Algunas de sus principales caracteristicas Compitado: La compilacién es el proceso de traducir el eédigo fuente que escribas en un lenguaje de mas bajo nivel — puede ser ensamblador (como en el caso de Go) w otto tipo de lenguaje intermedio (como en el caso de Java o C#)Los lenguajes compilados suelen ser ‘mis répidos y los ejecutables pueden funcionar sin depedencias adicionales (al ‘menos esto es cierto para lenguajes como C, C++ y Go, los cuales compilan directamente ‘en ensamblador) + Extaticamente Tipado: Estar tipado estéticamente implica que las variables deben ser de un tipo especifico (int, string, bool, [Jbyte, etc). Esto se consigue indicando el tipo a la hora de definir la variable o, en muchos casos, dejando al compilador que infiera el tipo Concurrent: Esta inspirado en CSP (Communicating sequential processes —de Charles Antony Hoare, ganador del premio Turing en 1980). + Uso poco usual de POO: Go no usa clases, no usa herencia y el uso de interfaces se realiza de manera implicita, Esto con el fin de mejorar el rendimiento al momento de diseftar ta software + Uso de paquetes: Se usan los paquetes para organizar el cédigo. Un paquete puede tener varios archivos “.g0” que permiten definir lo que va a realizar el paquete. Para usar un, paquete en tu programa, debes importarlo, « Recoleceién de Basura: Los lenguajes con recolectores de basura (e,., Ruby, Python, Java, JavaScript, C#, Go) son capaces de realizar un seguimiento de las variables y liberarlas ‘cuando no se utilicen mas. La recoleccién de basura afiade overhead, pero también elimina bugs devastadores La sintaxis de C suele implicar que las lineas deban terminar en punto y coma y que debe haber paréntesis que delimitan condicionales. Go acaba con estas pricticas, aunque los paréntesis se siguen usando para controlar la precedencia de operadores. hhttps://golang.org/ Ejecutar Cédigo Go en linea hitps://play. golang.org En Go, el punto de entrada de un programa es una funcién llamada main ubicada en el paquete main. Imports Go incluye ciertas funciones predefinidas, como printin, las cuales pueden ser utilizadas sin referenciar. No podemos ir muy lejos sin utilizar la libreria estdndar de Go y, eventualmente, sin usar librerias de terceros. En Go, la palabra clave import se utiliza para declarar qué paquetes van a ser utilizados por el cédigo del fichero en el que estemos trabajando. Go es estricto en lo que respecta a la importacién de paquetes, tanto que tu cbdigo no compilaré si importas un paquete que no utilizas. la libreria estdndar de Go esta bien documentada, ejemplo paquete fint hhtps://golang.org/pkg/fimt/ Tipos de datos Los datos l6gicos pueden almacenarse en variables de tipo bool. Los valores que pueden tener son true y false (en mindsculas). El valor cero (el valor por defecto) de las variables de tipo bool es false. Las operaciones que se pueden realizar en Go con elementos légicos son las siguientes: Operador | Operacién | Uso | Significado e iy Ipeaqipya in 10 Ipilaipog : 1 No ' INO p Los mimeros winte geo 8 285 inte de 0 a 6ss35 wines? de 0 2 4294967295 ance e128 8 127 amt1é de -22768 a 22767 snes? de -2147483642 0 2147429647 smeét de -9029972088 775808 a 9229972096854775807 floes? _niineros reales (coma flotance) de 32 bits (seqin TEEE-754) ‘Hloatét _mimeros reales (coma flotance) de 64 bits (segin TEFE-754) complexéi muineros conplejos con partes real © inaginaria de 32 bits compiexi2s mimeros conpiejos con partes real e inaginaria de €¢ bits bre Jo mismo que uinte one Jo mismo que inti2 wine. puede ser un uints2 0 un uinti6 segin 1a inplenencacién sme entero del miano tamafo que uint bintper entero euficientemente Largo para simacensr un puntero Cabe desatacar que no hay un tipo float String Las vemos mas abajo Operaciones + sume enteros, floats, complex values, strings - reste enteros, floats, complex values * multiplicacién enteros, floats, complex values 7 division enteros, floats, complex values % mbduto enteros © ¥ (bit a bir) enteros | 0 (it a bit) enteros = -XOR (bit a bit) enteros: «* NO (limpiar bits) enteros << desplazaniento izq entero << entero sin signo >> desplazamiento derecha entero >> entero sin signo ‘Comparaciones = igual, t= no igual > menor que <= menor o igual que > mayor que <= mayor o igual que en Go ¢s imprescindible indicar explfcitamente cualquier conversién. En Go las conversiones no devuelven errores en tiempo de ejecucién, Si un valor no encaja en otro tipo, se hace una simplificacién, Por ejemplo, al pasar de un float32 a int se elimina la parte decimal. Las conversiones se pueden utilizar para la conversién de tipos no numéricos. La sintaxis es siempre la misma: (variable). Variables y Declaraciones Go asigna un valor por defecto a las variables. A los enteros se les asigna 0, a los booleanos false, a Jos strings "" var mivariable int mivariable = 9000 0 con inferencia de tipos Es importante que recuerdes que := se utiliza para declarar la variable a la vez que se le asigna valor. {Por qué? Porque una variable no puede ser definida dos veces (al menos no en el mismo 4mbito). como ocurre con los imports, Go no te va a permitir tener variables sin utilizar. recuerda {que puedes usar var NOMBRE TIPO cuando delaras una variable y le asignas su valor por defecto, NOMBRE == VALOR cuando declaras y asignas valor a una variable, y NOMBRE = VALOR cuando asignas valor a una variable previamente declarada, Estructuras de control . oF La condicién se escribe sin paréntesis. No s6lo son opcionales, sino que la utilidad de formateo de cédigo Go los elimina de forma ratinaria. Al utilizar IF es imprescindible utilizar las Haves. No tenemos la opeién de no ponerlas y ejecutar sélo la siguiente instruccién. La condicién IF puede ir acompafiada de una una seccién ELSE. * FOR El uso de paréntesis en el FOR es opcional. También al igual que en el caso del IF, el formateador de cédigo elimina los paréntesis por ser innecesarios. For o while?? fune main) { contador := 0 for contador < 10 { contador = contador + 1 } fimt-PrintIn("Hemos contado hasta", contador) Q En el caso de Go, el WHILE s6lo se trata de un caso particular de FOR; no se necesita otra palabra reservada Si afiadimos una operacién de inicializacién y una de incremento func main) { vvar contador int for contador = 0; contador < 10; contador 1/Ahora el bucle esta vacio } fint.Println("Hemos contado hasta’, contador) } contador + 1 { Ambas opcionales , exactamente igual que en C/C++, DO.WHILE..no existe... (la sonrisa pertenece a la profe) © Range La palabra clave de rango se usa en bucles para iterar datos en estructuras de datos (matrices, segmentos, cadenas, mapas, etc.) 1. Con matrices y segmentos, el rango proporciona indices y valores. 2. Con los mapas, el rango proporciona pares clave-valor. 3. Con la cadena, el rango proporciona el indice de cada cardcter Unicode en la cadena y sus caracteres Unicode correspondientes. 4, Si los valores de indice no son necesarios, se pueden descartar utiizando _ fune main) { sum :=0 for indice, valor := range numeros{ sum += valor fmt.Print("[", indice, valor ,"]") int{ 1, 2, 3, 4, 5, 6, 7, 8,9, 10} } fmt.Printin("\nSum es :: ", sum) str = "Hello, World!" for indice, ¢ == range str { fmt.Print("[", indice, ",", string(c), " } Estructuras ‘Una estructura es una agrupacién ordenada de distintos elementos de informacién, Cada uno de ellos con su propio tipo de datos correspondiente. import "gmt" type fichaAlumno struct { nombre string //Nombre del alumno humano bool //True si el alumno es humano color int //Color del sable de luz en entero ) func main() var goPadawan fichaAlumno goPadawan.nombre = "GoPadawan" goPadawan-humano = true goPadawan.color = 65280 fmt.Printin("Informacién de GoPadawan:", goPadawan) } Declaracién de Funciones pueden devolver mas de un valor _ Pueden devolver mis de un valor _ func log(message string) {} fune add(a int, b int) int {} fume power(name string) (int, bool) {} Se puede usar una sintaxis abreviada si los parémetros son del mismo tipo: fune add, b int) int (} Funciones Variadicas Pueden ser llamadas con cualquier nimero de argumentos fume sum(nums ...int){...} sum(1, 2) sum(1, 2, 3), Array En Go los arrays estin implementados dentro del lenguaje. No son objetos, ni abstracciones externas, Forman parte intrinseca del lenguaje y su uso es muy intuitivo. Cuando definimos un array especificamos un tipo de elemento y el nimero de elementos. Ambos son inmutables y definen el tipo del array. Un array de 4 enteros es de un tipo distinto de un array de 5 enteros Definiendo arrays Vamos a definir unos cuantos arrays. Un array sin valores. Mejor dicho: un array cuyos elementos adquieren el valor cero. ‘var enteros [2]int Un array con dos elementos definidos. var eb [2}string = [2]string{"Epi", "Blas"} mn corta del caso anterior. string "Epi", "Blas"} én ain més corta eb := [2]string{"Epi", "Blas"} Definicién sin especificar (explicitamente) el tamafio del array. ‘Como en el resto de casos, a menos que especifiquemos el valor de los elementos del array, se inicializan con el valor cero. Los arrays en memoria Las variables que contienen un array ocupan en memoria el tamafio de cada elemento multiplicado por el niimero de elementos. Nada mas. Habiendo visto cémo es un array, veamos cémo NO es un array: + Unarray no es un puntero o una referencia ices Un slice es una estructura ligera que encapsula y representa una porcién de un array. Hay varias formas de crear un slice. puntaje == [Jint{1,4,293,4,9} crea ¢ inicializa una estructura de enteros 5 posiciones Otro modo es usar la funcién make que esta sobrecargada y tiene varios objetivos. Para declarar: puntaje += make([int, 10) Crea un slice de longitud 10 y capacidad 10. Esto significa que seria valido asignar valores a scores{0].. scores[]..... Scores[9].. recordemos que las estructuras enteras en Go se inicializan en 0, Longitud es el tamatio del slice y la capacidad es el tamaiio del array subyacente Ejemplo: fune main() { scores := make([Jint, 10) fmt .Print1n (scores) 10000000000) Si quisiéramos configurar por separado longitud y capacidad make({i untaj 0, 10) ‘Tendriamos un slice de longitud 0 y capacidad 10. f (Cual piensan que es la diferencia?? Que podemos y que no podemos hacer?? PRUEBEN! Sitiene longitud 0, como podemos utilizarlo entonces”? Necesitamos ampliar la longitud cexplicitamente o utilizar alguna funcién que lo haga. Modificar la longitud puntaje = puntaje[0:5] Esto amplia la longitud en 5, es0 nos permite poner datos en las posiciones 0 a4. El limite de la expansién explicita es la capacidad que hayamos dado. Expandir con append: Nos permite ir ocupando los espacios desde la posicién 0 en forma secuencial. puntaje = append(puntaje, 5) ‘Almacena en la posicién 0 el valor 5 2 f Si tengo mi slice con datos en las 10 posiciones segin la declaracién/inicializacion puntaje := make([Jint, 0, 10) y agrego un dato mas con append expandiendo el slice, cual seria la ongitud?? Y la capacidad?? Utilicen la funcién len para la longitud y cap para ver la capacidad. Son iguales?? Encuentran un patrén?? Los slice tienen internamente una estructura de tipo cabecera y elementos, los elementos en las funciones pasan por referencia, pero no asi la cabecera, La siguiente imagen muestra cémo se almacenan en memoria los slices: ‘Como se indica en la imagen, tenemos un puntero ptr que es un puntero (referencia) al array, una longitud len que contiene un entero (positive) con la longitud en uso, y una capacidad cap con la capacidad maxima de este slice. La siguiente imagen muestra un caso conereto: un trozo asociado a un array de S posiciones. Doe] 5 En este caso, el tamaiio y 1a capacidad tienen el mismo valor, Io que significa que el troz0 csté al maximo de su capacidad. ‘Veamos ahora un caso den el que el trozo “desecha” las primeras y iltimas posiciones del array. Slice concreto desechando las primeras y itima: Entonces como lo expandimos?? Podemos usar el make para declarar un nuevo slice mas grande y copiar los datos usando la funcién. copy(destino,origen). Go tiene una funcién que hace esto append, puntos = append(puntos, 4) agrega el 4 al slice puntos = append(puntos, puntos2...) concatena el slice? al slice original puntos? := append{({Jint(nil), puntos...) hace una copia String Las cadenas estin compuestas de letras y mimeros y pueden ser definidas usando comillas dobles, son solo slices de bytes de solo lectura con un poco de soporte sintactico adicional del lenguaje. barra: = "/ us / ken" [0] // produce el valor de byte '/" usr: = "/ usr / ken" [0: 4] // produce 1a subcadena "/ use” str: = string (oarra) // muestra el caracter Punteros - variables por referencia Go soporta apuntadores, lo cual nos permite pasar referencias de valores y datos entre las funciones de nuestro programa, El cédigo *iptr en el cuerpo de la funcidn dereferencta el apuntador de su direceién de memoria a el valor actual de esa direccién. Si asignamos un valor a un apuntador dereferenciado se cambia el valor que se esti almacenando en dicha direccién de memoria. La sintaxis &i devuelve la direccién en memoria de i, ie. un apuntador a i. EI: func zeroptr(ipte *int) ( wiptr = 0 } fune main() ( fisa zeroptr (éi) fmt .Printin ("zeropti xi", i) ///zexoptr: 0 3 Métodos ‘Los métodos estan asociados con Estructuras. type Persona struct { nombre string apellido string edad int t func (p *Persona) incrementaEdad() int { p.edadt+ return p.edad I fune main() { me:= Persona {"Bill", "Broughton", 29, "Brown", true} fint Printin(me.inerementaEdad()) // Output: 30 fint.Printin(me.edad) // Output: 30 En la prictica... Bésqueda binaria fune BusquedaBinaria(data [Jint, value int) bool { for Primero <= Ultimo { medio = Primero + (Ultimo - Primero)/2 iff datalmedio] == value { return true } else if data{medio] < value { Primero = medio + 1 } else { Ultimo = medio - 1 1 } return false

También podría gustarte