One place for hosting & domains

      sobre

      Información sobre GOPATH


      Introducción

      Este artículo le servirá como guía para comprender GOPATH, su funcionamiento y su configuración. Este paso es crucial para configurar un entorno de desarrollo de Go, así como para comprender cómo se ubican, instalan y construyen archivos de origen en Go. En este artículo, usaremos GOPATH al hacer referencia al concepto de estructura de carpetas que analizaremos. Usaremos $GOPATH para hacer referencia a la variable de entorno que se utiliza en Go para encontrar la estructura de carpetas.

      Un espacio de trabajo de Go es la alternativa con la que se administran en Go nuestros archivos de origen, binarios compilados y objetos almacenados en caché que se utilizan para acelerar la compilación posteriormente. Es habitual, y también aconsejable, tener solo un espacio de trabajo de Go, aunque es posible contar con varios. GOPATH funciona como una carpeta root de un espacio de trabajo.

      Configurar la variable de entorno $GOPATH

      En la variable de entorno $GOPATH se listan las ubicaciones para que en Go se busquen los espacios de trabajo de Go.

      Por defecto, en Go se supone que nuestra ubicación de GOPATH se encuentra en $HOME/go, donde $HOME es el directorio root de nuestra cuenta de usuario en nuestra computadora. Podemos cambiarlo configurando la variable de entorno $GOPATH. Para obtener más información, siga este tutorial sobre lectura y configuración de variables de entorno en Linux.

      Para obtener más información sobre la configuración de la variable $GOPATH, consulte la documentación de Go.

      Además, en esta serie se analizan la instalación de Go y la configuración de un entorno de desarrollo del mismo.

      $GOPATH No es $GOROOT

      $GOROOT es el punto en el que se encuentran el código, el compilador y las herramientas de Go, no es nuestro código fuente. $GOROOT generalmente es similar a /usr/local/go. Nuestra $GOPATH generalmente es similar a $HOME/go.

      Aunque ya no necesitamos configurar la variable $GOROOT específicamente , todavía se hace referencia a esta en documentos anteriores.

      Ahora, revisaremos la estructura del espacio de trabajo de Go.

      Anatomía del espacio de trabajo de Go

      Dentro de un espacio de trabajo de Go, o GOPATH, hay tres directorios: bin, pkg y src. Cada uno de estos directorios tiene un significado especial para las herramientas de Go.

      .
      ├── bin
      ├── pkg
      └── src
        └── github.com/foo/bar
          └── bar.go
      

      Revisemos cada uno de estos directorios.

      En el directorio $GOPATH/bin es donde Go dispone los binarios que se compilan en go install. Nuestro sistema operativo utiliza la variable de entorno $PATH para encontrar aplicaciones binarias que pueden ejecutarse sin una ruta completa. Se recomienda añadir este directorio a nuestra variable global $PATH.

      Por ejemplo, si no añadimos $GOPATH/bin a $PATH para ejecutar un programa desde este, tendríamos que ejecutar lo siguiente:

      Cuando $GOPATH/bin se añade a $PATH, podemos realizar la misma invocación como se muestra a continuación:

      En el directorio $GOPATH/pkg se almacenan los archivos de objetos previamente compilados de Go para acelerar la compilación posterior de los programas. Normalmente, la mayoría de los desarrolladores no necesitarán acceder a este directorio. Si experimenta problemas relacionados con la compilación, puede eliminar este directorio sin peligro; Go lo reconstruirá.

      El directorio src es el punto en el que todos nuestros archivos .go o de código fuente deben ubicarse. Esto no debe confundirse con el código fuente que se utiliza en la herramienta de Go, el cual se encuentra en el $GOROOT. A medida que escribamos aplicaciones, paquetes y bibliotecas de Go, dispondremos estos archivos en $GOPATH/src/path/to/code.

      ¿Qué son los paquetes?

      El código de Go se organiza en paquetes. Un paquete representa todos los archivos en un solo directorio en el disco. Un directorio solo puede contener ciertos archivos del mismo paquete. Los paquetes se almacenan, con todos los archivos de origen de Go escritos por los usuarios, en el directorio $GOPATH/src. Podemos comprender la resolución de paquetes importando diferentes paquetes.

      Si nuestro código reside en $GOPATH/src/blue/red, entonces el nombre de su paquete debería ser red.

      La instrucción import para el paquete red sería la siguiente:

      import "blue/red"
      

      Los paquetes que se alojan en los repositorios de código fuente, como GitHub y BitBucket, tienen la ubicación completa del repositorio como parte de su ruta de importación.

      Por ejemplo, importaríamos el código fuente de https://github.com/gobuffalo/buffalo usando la siguiente ruta de importación:

      import "github.com/gobuffalo/buffalo"
      

      Por lo tanto, este código fuente se encontraría en la siguiente ubicación en el disco:

      $GOPATH/src/github.com/gobuffalo/buffalo
      

      Conclusión

      A través de este artículo, analizamos GOPATH como un conjunto de carpetas en las que Go prevé que se encuentra nuestro código fuente, y también vimos qué son y qué contienen estas carpetas. Analizamos la forma de cambiar esa ubicación de la predeterminada $HOME/go por la que el usuario prefiera configurando la variable de entorno $GOPATH. Por último, analizamos la forma en que Go se busca paquetes dentro de esa estructura de carpetas.

      Los Go Modules se introdujeron en Go 1.11 y su propósito es sustituir los espacios de trabajo de Go y GOPATH. Si bien se recomienda comenzar a usar módulos, es posible que algunos entornos, como los corporativos, no estén listos para utilizar módulos.

      GOPATH es uno de los aspectos más complicados de la configuración de Go, pero una vez que está listo normalmente no hay de qué preocuparse.



      Source link

      Información sobre clases de JavaScript


      Introducción

      JavaScript es un lenguaje basado en prototipos y cada objeto en él tiene una propiedad interna oculta llamada [[Prototype]] que puede usarse para extender propiedades y métodos de objetos. Puede obtener más información sobre los prototipos de nuestro tutorial Información sobre los prototipos y la herencia en JavaScript.

      Hasta hace poco, los desarrolladores esforzados usaban funciones constructoras para imitar un patrón de diseño orientado a objetos en JavaScript. La especificación de lenguaje ECMAScript 2015, a menudo denominada ES6, introdujo clases en el lenguaje JavaScript. Las clases de JavaScript no ofrecen realmente una funcionalidad adicional y a menudo se describen como elementos que aportan “azúcar sintáctico” en comparación con los prototipos y la herencia, ya que ofrecen una sintaxis más limpia y elegante. Debido a que otros lenguajes de programación usan clases, la sintaxis de clase de JavaScript permite que los desarrolladores alternen lenguajes de forma más directa.

      Las clases son funciones

      Una clase de JavaScript es un tipo de función. Las clases se declaran con la palabra clave class. Usaremos sintaxis de expresión de función para inicializar una sintaxis de expresión de función y clase para inicializar una clase.

      // Initializing a function with a function expression
      const x = function() {}
      
      // Initializing a class with a class expression
      const y = class {}
      

      Podemos acceder a [[Prototype]] de un objeto usando el métodoObject.getPrototypeOf(). Usaremos eso para probar la función vacía que creamos.

      Object.getPrototypeOf(x);
      

      Output

      ƒ () { [native code] }

      También podemos usar ese método en la clase que acabamos de crear.

      Object.getPrototypeOf(y);
      

      Output

      ƒ () { [native code] }

      El código declarado con function y class muestra una función [[Prototype]]. Con prototipos, cualquier función puede convertirse en una instancia de constructor mediane la palabra clave new.

      const x = function() {}
      
      // Initialize a constructor from a function
      const constructorFromFunction = new x();
      
      console.log(constructorFromFunction);
      

      Output

      x {} constructor: ƒ ()

      Esto se aplica a clases también.

      const y = class {}
      
      // Initialize a constructor from a class
      const constructorFromClass = new y();
      
      console.log(constructorFromClass);
      

      Output

      y {} constructor: class

      Estos ejemplos de constructores de prototipos, de lo contrario, están vacíos. Sin embargo, podemos ver que debajo de la sintaxis ambos métodos logran el mismo resultado final.

      Definir una clase

      En el tutorial de prototipos y herencia, confeccionamos un ejemplo basado en la creación de personajes en un juego de roles basado en texto. Continuaremos con ese ejemplo aquí para actualizar la sintaxis de funciones a clases.

      Una función constructora se inicializa con varios parámetros que se asignarían como propiedades de this, en alusión a la propia función. La primera letra del identificador sería mayúscula por convención.

      constructor.js

      // Initializing a constructor function
      function Hero(name, level) {
          this.name = name;
          this.level = level;
      }
      

      Cuando traducimos esto a la sintaxis de clase, que se muestra a continuación, vemos que su estructura es bastante similar.

      class.js

      // Initializing a class definition
      class Hero {
          constructor(name, level) {
              this.name = name;
              this.level = level;
          }
      }
      

      Sabemos que una función constructora está pensada para ser un esquema de objeto por el uso de mayúscula en la primera letra del inicializador (opcional) y a través de la familiaridad con la sintaxis. La palabra clave class comunica de una manera más directa el objetivo de nuestra función.

      La única diferencia en la sintaxis de la inicialización tiene que ver con el uso de la palabra clave class en lugar de function, y con la asignación de las propiedades dentro de un método constructor().

      Definir métodos

      La práctica común con funciones constructoras consiste en asignar métodos directamente a prototype en lugar de hacerlo con la initialización, como se aprecia en el método greet() a continuación.

      constructor.js

      function Hero(name, level) {
          this.name = name;
          this.level = level;
      }
      
      // Adding a method to the constructor
      Hero.prototype.greet = function() {
          return `${this.name} says hello.`;
      }
      

      Con clases, esta sintaxis se simplifica y el método puede agregarse directamente a las clases. Al usar la abreviatura de definición de método introducida en ES6, se logra una concisión aun mayor al definir un método.

      class.js

      class Hero {
          constructor(name, level) {
              this.name = name;
              this.level = level;
          }
      
          // Adding a method to the constructor
          greet() {
              return `${this.name} says hello.`;
          }
      }
      

      Observemos estas propiedades y métodos en acción. Crearemos una nueva instancia de Hero usando la palabra clave new y asignaremos algunos valores.

      const hero1 = new Hero('Varg', 1);
      

      Si imprimimos más información sobre nuestro nuevo objeto con console.log(hero1), podemos apreciar más detalles sobre lo que sucede con la inicialización de clase.

      Output

      Hero {name: "Varg", level: 1} __proto__: ▶ constructor: class Hero ▶ greet: ƒ greet()

      Podemos ver en el resultado que las funciones constructor() y greet() se aplicaron a __proto__, o [[Prototype]] de hero1, y no directamente como método en el objeto hero1. Aunque esto queda de manifiesto en la creación de funciones de constructor, no resulta evidente al crear clases. Las clases permiten una sintaxis más sencilla y sucinta, aunque sacrifican algo de claridad en el proceso.

      Ampliar una clase

      Una característica ventajosa de las funciones y clases constructoras es que pueden ampliarse a nuevos esquemas de objeto basados en el elemento principal. Esto impide la repetición de código para objetos similares, pero necesitan características adicionales o más específicas.

      Se pueden crear nuevas funciones constructoras desde el elemento principal usando el método call(). En el siguiente ejemplo, crearemos una clase de carácter más específica llamada Mage y le asignaremos las propiedades de Hero usando call(), además de agregar una propiedad.

      constructor.js

      // Creating a new constructor from the parent
      function Mage(name, level, spell) {
          // Chain constructor with call
          Hero.call(this, name, level);
      
          this.spell = spell;
      }
      

      En este punto, podemos crear una nueva instancia de Mage usando las mismas propiedades de Hero, así como también una nueva que agregamos.

      const hero2 = new Mage('Lejon', 2, 'Magic Missile');
      

      Al enviar hero2 a la consola, podemos apreciar que creamos una nueva clase Mage basada en la constructora.

      Output

      Mage {name: "Lejon", level: 2, spell: "Magic Missile"} __proto__: ▶ constructor: ƒ Mage(name, level, spell)

      Con clases de ES6, la palabra clave super se usa en lugar de call para acceder a las funciones principales. Usaremos extends para hacer referencia a la clase principal.

      class.js

      // Creating a new class from the parent
      class Mage extends Hero {
          constructor(name, level, spell) {
              // Chain constructor with super
              super(name, level);
      
              // Add a new property
              this.spell = spell;
          }
      }
      

      Ahora podemos crear una nueva instancia de Mage de la misma manera.

      const hero2 = new Mage('Lejon', 2, 'Magic Missile');
      

      Imprimiremos hero2 en la consola y veremos el resultado.

      Output

      Mage {name: "Lejon", level: 2, spell: "Magic Missile"} __proto__: Hero ▶ constructor: class Mage

      El resultado es casi exactamente el mismo, con la diferencia de que en la construcción de clase [[Prototype]] se vincula al elemento principal; en este caso, Hero.

      A continuación, se muestra una comparación en paralelo de todo el proceso de inicialización, incorporación de métodos y herencia de una función constructor y una clase.

      constructor.js

      function Hero(name, level) {
          this.name = name;
          this.level = level;
      }
      
      // Adding a method to the constructor
      Hero.prototype.greet = function() {
          return `${this.name} says hello.`;
      }
      
      // Creating a new constructor from the parent
      function Mage(name, level, spell) {
          // Chain constructor with call
          Hero.call(this, name, level);
      
          this.spell = spell;
      }
      

      class.js

      // Initializing a class
      class Hero {
          constructor(name, level) {
              this.name = name;
              this.level = level;
          }
      
          // Adding a method to the constructor
          greet() {
              return `${this.name} says hello.`;
          }
      }
      
      // Creating a new class from the parent
      class Mage extends Hero {
          constructor(name, level, spell) {
              // Chain constructor with super
              super(name, level);
      
              // Add a new property
              this.spell = spell;
          }
      }
      

      Aunque la sintaxis es bastante distinta, el resultado subyacente es casi el mismo para ambos métodos. Las clases nos ofrecen una alternativa más concisa para crear esquemas de objeto y las funciones constructor describen con mayor precisión lo que sucede en segundo plano.

      Conclusión

      En este tutorial, incorporó conocimientos sobre las similitudes y diferencias entre las funciones constructor de JavaScript y las clases de ES6. Tanto las clases como las funciones constructor imitan un modelo de herencia orientado hacia objetos para JavaScript, que es un lenguaje de herencia basado en prototipos.

      Comprender la herencia prototípica es primordial para desempeñarse con eficacia como desarrollador de JavaScript. Familiarizarse con las clases es extremadamente útil, ya que en las bibliotecas de JavaScript populares como React se usa con frecuencia la sintaxis class.



      Source link