Go: propuesta: especificación: literales enteros binarios

Creado en 27 feb. 2017  ·  91Comentarios  ·  Fuente: golang/go

Actualmente, Go admite literales enteros octales y hexadecimales además de los literales decimales estándar que cabría esperar. En un esfuerzo por completar este grupo, propongo agregar también literales enteros binarios. Vendrían en la forma como un nuevo prefijo para literales enteros: 0b o 0B .

Descargo de responsabilidad inicial

Esta fue mi primera inmersión en el código fuente de Go y principalmente una experiencia de aprendizaje para que me mojara los pies enviando cambios y demás. Dicho esto, agradezco todas y cada una de las críticas, comentarios y sugerencias.

El "por qué": estado de la técnica

Los literales binarios también existen o han aparecido en los idiomas principales, que incluyen:

Todos los casos anteriores se han establecido en una convención de usar 0b o 0B para prefijar literales binarios, lo que sugiere que esta sería una opción bastante cómoda y sensata para Go también, evitando inventos innecesarios y proporcionando similitud para los programadores que provienen de estos otros lenguajes antes mencionados.

El "por qué": continuación

Me las arreglé para encontrar algunas discusiones anteriores relacionadas con esto, aunque esto fue después de que ya había implementado la función y tiene más que ver con cambiar la sintaxis octal que específicamente con los literales binarios. Pero https://github.com/golang/go/issues/12711#issuecomment -142338246 de @griesemer menciona que "tanto la 'o' para octal como la 'b' para notación binaria también se discutieron en el diseño de Go. Simplemente no es suficiente por el dinero ". Sin embargo, no veo esto como un buen argumento en contra de agregar algo tan simple al lenguaje. Especialmente considerando el hecho de que hoy en día más y más lenguajes han adoptado la sintaxis para literales binarios, parece que las decisiones de diseño de Go anteriores podrían necesitar ser analizadas bajo una nueva luz.

Uso de ejemplo

const (
    SOME_MASK   = 0b00001111
    SOME_FLAG_A = 0b00000001
    SOME_FLAG_B = 0b00000010
    SOME_FLAG_C = 0b00000100
    SOME_FLAG_D = 0b00001000
)

Implementación

Como dije que esto fue más una experiencia de aprendizaje para mí, ya tengo listos los cambios que implementan esta función:

Especificación CL-37502 : especifique la sintaxis para literales enteros binarios
CL-37503 cmd / compile / internal / syntax: escanear literales binarios
CL-37504 go / scanner: escanea literales enteros binarios
CL-37505 strconv: admite el análisis de literales enteros binarios
Prueba CL-37506 : extienda int_lit con usos literales binarios

FrozenDueToAge Go2 LanguageChange NeedsDecision Proposal Proposal-Accepted

Comentario más útil

Veamos por qué los lenguajes mencionados anteriormente han avanzado y han agregado soporte para literales binarios. Comencemos con C ++ 14, ya que es el primero de la lista. ¿Cuáles fueron los puntos que planteó James Dennett, entonces empleado de Google?

El uso de un prefijo 0b / 0B para literales binarios es una extensión de GCC existente (también compatible con Clang) y tiene la misma sintaxis que Java 7, Python y D.

¿Por qué beneficiaría a Go este punto en particular?

Familiaridad con el idioma.

Muchos desarrolladores pasan del lenguaje de programación al lenguaje de programación. Corrígeme si me equivoco, pero todos probamos lo que sabemos de un idioma en otro. De alguna manera, se podría decir que la familiaridad de Go con C y C ++ atrajo a ese tipo de desarrolladores que querían una característica en particular como GC, pero no les gustaban otros lenguajes. Esta es una de las razones por las que la empresa para la que actualmente hago prácticas ha decidido mudarse a Go.

Además de los desarrolladores experimentados, también echemos un vistazo a las ventajas de la familiaridad para los desarrolladores principiantes. Tomemos también el caso de uso de las banderas que mencionó @eddieringle . Explicarle a un principiante cómo funcionan las banderas es mucho más difícil cuando tienes que explicarlo en octal o hexadecimal, ya que requiere que la persona las aprenda también.

Por último, me gustaría agregar aquí que el propósito de cada idioma (al menos eso es lo que espero) es escribir código limpio. Y creo que es algo en lo que todos estamos de acuerdo independientemente. Al mirar el código de otra persona, queda inmediatamente claro sin ninguna explicación que cuando se tiene una lista de constantes literales binarias, esas son banderas. Lo mismo es mucho menos sencillo cuando se usa hexadecimal u octal. A continuación se muestra una comparación.

// Hexadecimal
const (
    MASK          = 0x1E
    DEFAULT_COLOR = 0x00
    BOLD          = 0x01
    UNDERLINE     = 0x02
    FLASHING_TEXT = 0x04
    NO_CHANGE     = 0x08
)

// Octal
const (
    MASK          = 036
    DEFAULT_COLOR = 00
    BOLD          = 01
    UNDERLINE     = 02
    FLASHING_TEXT = 04
    NO_CHANGE     = 010
)

// Binary
const (
    MASK          = 0b11110
    DEFAULT_COLOR = 0b00000
    BOLD          = 0b00001
    UNDERLINE     = 0b00010
    FLASHING_TEXT = 0b00100
    NO_CHANGE     = 0b01000
)

Creo que no es necesario pensar en el hecho de que las últimas constantes se utilizan para las banderas. Estas también son muy pocas banderas, así que tenga en cuenta que esto definitivamente se suma cuando tiene más banderas. La primera constante 0x1E definitivamente puede llamar la atención cuando se declara sin contexto. El uso de literales binarios por sí solos puede indicar que una variable podría usarse como bandera.

El PDF de C ++ mencionado se refiere además a los lenguajes mencionados anteriormente para obtener soporte. Así que veamos los siguientes. Encontré la propuesta (¿original?) De Derek Foster en 2009 para literales binarios en JDK. Fuente

Lo primero que cuestiona, con lo que estoy completamente de acuerdo, es por qué hay una representación octal en el JDK, pero no hay una representación binaria en el JDK. En los últimos años nunca he pensado para mí mismo: "¡Oh, los octales harían mi código más limpio!" Sin embargo, esto se refiere al punto anterior que hice: familiaridad . Sin embargo, hay una cosa que agrega a mi punto anterior:

Sin embargo, cuando los datos que se tratan están orientados fundamentalmente a bits, el uso de hexadecimal para representar rangos de bits requiere un grado adicional de traducción para el programador, y esto a menudo puede convertirse en una fuente de errores. [...] entonces, un programador que codifique esa especificación debe traducir cada uno de esos valores de su representación binaria a hexadecimal. [...] En la mayoría de los casos, los programadores hacen estas traducciones en sus cabezas y ESPERAMOS que las hagan bien. sin embargo, los errores pueden aparecer fácilmente y volver a verificar los resultados no es lo suficientemente sencillo como para hacerlo con frecuencia.

La notación hexadecimal y octal utilizada principalmente en hardware en lugar de binaria puede provocar errores humanos. En la comparación que di anteriormente, verifiqué lo que hice con mi cabeza ingresando lo que pensé que era octal en Google, lo que confirmó mis respuestas. Estoy automáticamente seguro de mi caso cuando lo escribo en binario, pero no lo estoy cuando lo escribo en hexadecimal u octal. Y no importa cuántas veces lo hagas al día, es más difícil escribir código porque tienes que pensar en la forma binaria en tu cabeza y mientras lo haces es posible cometer errores.

Para profundizar en la pregunta de por qué hay una notación octal, pero no una notación binaria, tengo otra pregunta que también hizo Derek Foster, el autor de la propuesta literal binaria para el JDK: "¿Por qué Go eligió usar el prefijo 0 para notaciones octales? " @griesemer comentó que no debemos

Esperemos y veamos qué dicen otras personas antes de saltar el arma. Gracias.

Pero, ¿no ha saltado Go al implementar la notación octal? Si su argumento era "porque otros lenguajes lo hacen", entonces ¿por qué no se puede usar ese argumento para literales binarios? Si no fue así, ¿cuál fue la razón por la que el prefijo 0 para las notaciones octales se incorporó al idioma cuando confunde a las personas?

Alguien podría pensar incorrectamente que "0b1" representa el mismo valor que el número hexadecimal "0xB1". Sin embargo, tenga en cuenta que este problema ha existido para octal / decimal durante muchos años (confusión entre "050" y "50") y no parece ser un problema importante.

- Derek Foster

No parece haber más puntos a favor de los literales binarios porque es algo a lo que todos nos referimos mentalmente. Por eso siento que las propuestas para otros idiomas han sido breves como esta. Sin embargo, no es una razón para apagarlo tan rápido.

Todos 91 comentarios

Esto ha llegado antes. Hay una gran cantidad de trabajo involucrado en la implementación de esto, por lo que hacer que el compilador y los cambios en las especificaciones sean triviales. Pero hay muchas bibliotecas que también deberían ser consistentes (strconv, math / big, etc.).

Si hacemos un cambio en esta dirección, debería ser más completo y apoyar bases arbitrarias. Estoy en contra de esto tal cual.

@griesemer Sí, los cambios que estoy a punto de enviar también modifican strconv (según tengo entendido, en realidad es necesario para respaldar este cambio).

@griesemer No estoy de acuerdo, sin embargo, en que cualquier cambio deba respaldar bases arbitrarias o de lo contrario no se realizará ningún cambio. Según la lectura anterior, parece que ese sería un buen objetivo para Go2; esto es simplemente pulir Go1 con la sintaxis que los desarrolladores de otros lenguajes podrían esperar al usar Go. (es decir, Base-2 es un caso bastante común, probablemente más común que octal; base-14 o lo que sea lo es menos.)

CL https://golang.org/cl/37503 menciona este problema.

CL https://golang.org/cl/37504 menciona este problema.

CL https://golang.org/cl/37502 menciona este problema.

CL https://golang.org/cl/37505 menciona este problema.

CL https://golang.org/cl/37506 menciona este problema.

Sin embargo, no veo esto como un buen argumento en contra de agregar algo tan simple al lenguaje.

Tampoco es un argumento particularmente fuerte a favor de agregarlos.

En mi humilde opinión, necesitará expandir la sección "por qué" explicando exactamente qué ventajas brindará el soporte de literales binarios a las personas que escriben código go.

No los encuentro particularmente útiles; hex es un formato mucho más legible y compacto para literales que tienen un "significado a nivel de bits".

Dio un 'ejemplo de uso', pero no es muy convincente. Escribiría esas constantes usando 0xf sy cambios para los demás.

@EddieRingle Esta propuesta no se ha debatido ampliamente ni ha sido aceptada. Por favor, no nos envíe spam con revisiones de código. El Go Team tiene bastante que ver con el trabajo que es realmente importante.

Está claro para todos que agregar una característica simple al lenguaje es trivial. También está claro que a mucha gente le gustaría esta función (a mí me hubiera gustado alguna vez). Pero dicho esto, solo porque uno puede, no es un argumento que deba. Cualquier adición pequeña y simple a un idioma tiene costos a largo plazo. Si aceptamos esto, será aún más difícil en el futuro tener un mecanismo más general, y debemos seguir siendo compatibles con versiones anteriores.

Esperemos y veamos qué dicen otras personas antes de saltar el arma. Gracias.

Recordatorio de nuestra política de no-yo-también: https://golang.org/wiki/NoMeToo

Las opiniones sin contenido constructivo se pueden expresar utilizando las reacciones emoji de Github.

@ALTree

En mi humilde opinión, necesitará expandir la sección "por qué" explicando exactamente qué ventajas brindará el soporte de literales binarios a las personas que escriben código go.

No los encuentro particularmente útiles; hexadecimal es un formato mucho más legible y compacto para literales que tienen un "significado a nivel de bits", en mi opinión.

En realidad, diría lo contrario. Hex es más compacto en muchos casos, sí, pero los literales binarios serían una representación exacta de "nivel de bits" y, por lo tanto, lo más legible posible.

@griesemer

Esta propuesta no se ha debatido ampliamente ni ha sido aceptada. Por favor, no nos envíe spam con revisiones de código. El Go Team tiene bastante que ver con el trabajo que es realmente importante.

Disculpas. Originalmente fue un solo cambio, pero como parece que la política de Go es dividir las confirmaciones en función del área de la base de código afectada, así es como terminé dividiéndolas. No sabía que el bot haría comentarios individuales aquí para cada cambio. Sin embargo, no sería tan frío como para llamarlo spam, ni insinuar que cualquier esfuerzo que ponga en usar mi tiempo libre no sea importante.

Cualquier adición pequeña y simple a un idioma tiene costos a largo plazo. Si aceptamos esto, será aún más difícil en el futuro tener un mecanismo más general, y debemos seguir siendo compatibles con versiones anteriores.

Como se mencionó anteriormente, la ruta de propósito general (que yo también preferiría) también alentaría la desaprobación / eliminación de la sintaxis octal existente (confusa), ¿no? La sensación que tuve fue que la sintaxis de propósito general ( 2r0010 o 2x0010 para base-2, por ejemplo) fue una invención pensada para Go2, donde los cambios de ruptura serían bienvenidos de todos modos.

Dejando a un lado un potencial Go2, para abordar la afirmación de que "_si aceptamos esto, será aún más difícil en el futuro tener un mecanismo más general_": simplemente no veo cómo esto es cierto. Agregar el prefijo literal binario sería ortogonal a una sintaxis alternativa de propósito general, especialmente la que describió en # 12711 (de hecho, esa sintaxis entra en conflicto directamente con los literales hexadecimales, pero no con esta sintaxis literal binaria propuesta). Existirían lado a lado tal como lo haría la sintaxis de propósito general con los literales octales, hexadecimales y decimales existentes.

Disculpas. Originalmente fue un solo cambio, pero como parece que la política de Go es dividir las confirmaciones en función del área de la base de código afectada, así es como terminé dividiéndolas. No sabía que el bot haría comentarios individuales aquí para cada cambio. Sin embargo, no sería tan frío como para llamarlo spam, ni insinuar que cualquier esfuerzo que ponga en usar mi tiempo libre no sea importante.

No se trata solo de que el bot envíe correo sobre CL, es que cada CL enviado por correo es una solicitud para que un revisor de Go dedique tiempo a revisarlo.

La sintaxis 0b es agradable porque es familiar, pero si el verdadero objetivo es simplemente agregar literales binarios al lenguaje, preferiría la solución genérica a la familiar.

¿Existe alguna razón técnica por la que la opción genérica no se pueda implementar antes de la 2.0? Últimamente he tenido varios casos en los que se habrían preferido los literales binarios en lugar de hexadecimal y sería bueno tener esa opción en 1.9 o 1.10 en lugar de esperar (posiblemente muchos años) hasta 2.0.

@wedow Creo que ayudaría ver casos reales específicos en los que los literales binarios son útiles. Comparta los casos en los que los literales binarios serían útiles. Gracias.

No veo que "debería apoyar bases arbitrarias" como una objeción que valga la pena. Agrega complejidad / costo por poco o ningún beneficio adicional. A lo largo de todos los años que he estado pirateando, las bases útiles que he escuchado de las personas que desean usar son 2, 8, 10, 12 y 16, y posiblemente 64 (después de todo, tenemos codificación base64) .

Veamos por qué los lenguajes mencionados anteriormente han avanzado y han agregado soporte para literales binarios. Comencemos con C ++ 14, ya que es el primero de la lista. ¿Cuáles fueron los puntos que planteó James Dennett, entonces empleado de Google?

El uso de un prefijo 0b / 0B para literales binarios es una extensión de GCC existente (también compatible con Clang) y tiene la misma sintaxis que Java 7, Python y D.

¿Por qué beneficiaría a Go este punto en particular?

Familiaridad con el idioma.

Muchos desarrolladores pasan del lenguaje de programación al lenguaje de programación. Corrígeme si me equivoco, pero todos probamos lo que sabemos de un idioma en otro. De alguna manera, se podría decir que la familiaridad de Go con C y C ++ atrajo a ese tipo de desarrolladores que querían una característica en particular como GC, pero no les gustaban otros lenguajes. Esta es una de las razones por las que la empresa para la que actualmente hago prácticas ha decidido mudarse a Go.

Además de los desarrolladores experimentados, también echemos un vistazo a las ventajas de la familiaridad para los desarrolladores principiantes. Tomemos también el caso de uso de las banderas que mencionó @eddieringle . Explicarle a un principiante cómo funcionan las banderas es mucho más difícil cuando tienes que explicarlo en octal o hexadecimal, ya que requiere que la persona las aprenda también.

Por último, me gustaría agregar aquí que el propósito de cada idioma (al menos eso es lo que espero) es escribir código limpio. Y creo que es algo en lo que todos estamos de acuerdo independientemente. Al mirar el código de otra persona, queda inmediatamente claro sin ninguna explicación que cuando se tiene una lista de constantes literales binarias, esas son banderas. Lo mismo es mucho menos sencillo cuando se usa hexadecimal u octal. A continuación se muestra una comparación.

// Hexadecimal
const (
    MASK          = 0x1E
    DEFAULT_COLOR = 0x00
    BOLD          = 0x01
    UNDERLINE     = 0x02
    FLASHING_TEXT = 0x04
    NO_CHANGE     = 0x08
)

// Octal
const (
    MASK          = 036
    DEFAULT_COLOR = 00
    BOLD          = 01
    UNDERLINE     = 02
    FLASHING_TEXT = 04
    NO_CHANGE     = 010
)

// Binary
const (
    MASK          = 0b11110
    DEFAULT_COLOR = 0b00000
    BOLD          = 0b00001
    UNDERLINE     = 0b00010
    FLASHING_TEXT = 0b00100
    NO_CHANGE     = 0b01000
)

Creo que no es necesario pensar en el hecho de que las últimas constantes se utilizan para las banderas. Estas también son muy pocas banderas, así que tenga en cuenta que esto definitivamente se suma cuando tiene más banderas. La primera constante 0x1E definitivamente puede llamar la atención cuando se declara sin contexto. El uso de literales binarios por sí solos puede indicar que una variable podría usarse como bandera.

El PDF de C ++ mencionado se refiere además a los lenguajes mencionados anteriormente para obtener soporte. Así que veamos los siguientes. Encontré la propuesta (¿original?) De Derek Foster en 2009 para literales binarios en JDK. Fuente

Lo primero que cuestiona, con lo que estoy completamente de acuerdo, es por qué hay una representación octal en el JDK, pero no hay una representación binaria en el JDK. En los últimos años nunca he pensado para mí mismo: "¡Oh, los octales harían mi código más limpio!" Sin embargo, esto se refiere al punto anterior que hice: familiaridad . Sin embargo, hay una cosa que agrega a mi punto anterior:

Sin embargo, cuando los datos que se tratan están orientados fundamentalmente a bits, el uso de hexadecimal para representar rangos de bits requiere un grado adicional de traducción para el programador, y esto a menudo puede convertirse en una fuente de errores. [...] entonces, un programador que codifique esa especificación debe traducir cada uno de esos valores de su representación binaria a hexadecimal. [...] En la mayoría de los casos, los programadores hacen estas traducciones en sus cabezas y ESPERAMOS que las hagan bien. sin embargo, los errores pueden aparecer fácilmente y volver a verificar los resultados no es lo suficientemente sencillo como para hacerlo con frecuencia.

La notación hexadecimal y octal utilizada principalmente en hardware en lugar de binaria puede provocar errores humanos. En la comparación que di anteriormente, verifiqué lo que hice con mi cabeza ingresando lo que pensé que era octal en Google, lo que confirmó mis respuestas. Estoy automáticamente seguro de mi caso cuando lo escribo en binario, pero no lo estoy cuando lo escribo en hexadecimal u octal. Y no importa cuántas veces lo hagas al día, es más difícil escribir código porque tienes que pensar en la forma binaria en tu cabeza y mientras lo haces es posible cometer errores.

Para profundizar en la pregunta de por qué hay una notación octal, pero no una notación binaria, tengo otra pregunta que también hizo Derek Foster, el autor de la propuesta literal binaria para el JDK: "¿Por qué Go eligió usar el prefijo 0 para notaciones octales? " @griesemer comentó que no debemos

Esperemos y veamos qué dicen otras personas antes de saltar el arma. Gracias.

Pero, ¿no ha saltado Go al implementar la notación octal? Si su argumento era "porque otros lenguajes lo hacen", entonces ¿por qué no se puede usar ese argumento para literales binarios? Si no fue así, ¿cuál fue la razón por la que el prefijo 0 para las notaciones octales se incorporó al idioma cuando confunde a las personas?

Alguien podría pensar incorrectamente que "0b1" representa el mismo valor que el número hexadecimal "0xB1". Sin embargo, tenga en cuenta que este problema ha existido para octal / decimal durante muchos años (confusión entre "050" y "50") y no parece ser un problema importante.

- Derek Foster

No parece haber más puntos a favor de los literales binarios porque es algo a lo que todos nos referimos mentalmente. Por eso siento que las propuestas para otros idiomas han sido breves como esta. Sin embargo, no es una razón para apagarlo tan rápido.

Aquí hay otra opción, que me parece más clara que cualquiera de las constantes enteras.

// Shifts
const (
    MASK          = 0x1e
    DEFAULT_COLOR = 0
    BOLD          = 1<<0
    UNDERLINE     = 1<<1
    FLASHING_TEXT = 1<<2
    NO_CHANGE     = 1<<3
)

(¿Y la máscara no debería ser 0xf, no 0x1e?)

Estoy ligeramente en contra de agregar constantes binarias, al menos en Go 1. Sin embargo, estaría a favor de agregarlas en Go 2. La razón de la diferencia es que si por alguna razón alguien se queda atascado en Go 1.8, cuando Go 1.9 sale con constantes binarias, si una de las importaciones (transitivas) del código de esa persona usa constantes binarias, entonces ya no pueden construir sus proyecto usando Go 1.8. Tendrían que vender o actualizar. Hay un costo definido por agregar una característica incompatible con versiones posteriores que debería pesar en contra de su utilidad.

Estoy de acuerdo en que no veo ninguna necesidad de bases que no estén en {2,8,10,16}. El caso de octal parece particularmente inestable, estaría a favor de eliminar octal en Go 2.

@ randall77 No estoy de acuerdo con que el cambio se vea más limpio. En mi cabeza todavía los estoy representando como números binarios y probablemente siempre lo haré. Sería más fácil eliminar ese cálculo que hago en mi cabeza.

(¿Y la máscara no debería ser 0xf, no 0x1e?)

El nombre MASK simplemente se tomó de la propuesta de JDK y no está realmente en línea con las otras constantes. Pero sí muestra que 0x1E y los hexadecimales ya causan confusión.

Puedo entender el punto que estás tratando de hacer al querer moverlo a Go 2. Pero no estoy de acuerdo en que debamos tener que apoyar proyectos que degraden su versión de Go de 1.9 a 1.8. Haría que lidiar con los cambios de idiomas sea una pesadilla. Sin embargo, no sé cómo ve esto Go, sería más prudente seguir la compatibilidad que Go tiene en mente.

Apoyo de todo corazón su posición sobre la eliminación de octal en Go 2.

Acabo de volver a leer mi comentario anterior (específicamente, "El equipo de Go tiene suficiente que ver con el trabajo que es realmente importante"). Quiero disculparme por esta declaración, que fue una formulación bastante ofensiva de lo que realmente quise decir. Así que déjame intentarlo de nuevo, elaborando un poco más y, con suerte, encontrando el tono correcto esta vez:

Apreciamos las propuestas que están bien fundamentadas y, si es necesario, vienen con implementaciones de prototipos. Dicho esto, el proceso de propuesta de Go es ligero a propósito, y el proponente no requiere trabajo adicional a menos que se solicite o sea necesario para comprender la propuesta. Enviar listas de cambios que no se solicitan y / o que no solucionan un problema es contraproducente, ya que alguien tendrá que tomarse el tiempo y revisarlas (aunque solo sea para posponerlas o cerrarlas). Un mejor enfoque, si uno quiere hacer un prototipo / escribir el código con anticipación, es vincular los cambios a otros lugares (por ejemplo, una confirmación privada de GitHub). Esto dejará la elección al equipo de Go y a los colaboradores externos: pueden decidir ver ese código si lo desean, o centrarse en elementos de mayor prioridad. Gracias.

@griesemer Gotcha, lo entiendo y eso tiene sentido. Asumí que el equipo de Go trataba a su Gerrit como AOSP hace con el suyo, y pensé que mis cambios podrían existir allí mientras se discutía esto. De todos modos, vincular a una sucursal aquí en GitHub es menos trabajo, por lo que es beneficioso para todos, supongo. :)

De hecho, hice el trabajo primero, ya que mi objetivo principal era piratear el compilador. Fue después del hecho que decidí presentarlo como propuesta.

@AndreasBackx El 0 a la

Al definir constantes de 1-set-bit, el cambio es más legible que 0b00001000..00 por la sencilla razón de que en la versión de cambio no es necesario contar un montón de ceros en la pantalla solo para entender qué bit está configurado ; acaba de leer el valor de cambio.

0b100000000000000000000000 frente a 1 << 23

En lo que respecta al uso en el mundo real, un método común de codificación de enteros de longitud variable es usar el bit alto para "leer más". Tuve que usarlo para extraer git packfiles. Aquí está el código para extraer los bits inferiores en varias bases:

by 127
b & 0x1f
b & 0177
b & 0b01111111

Personalmente, creo que la versión binaria muestra más claramente la intención.

Todavía tienes la opción de turno mencionada anteriormente
Si cree que no es legible, use una función auxiliar

b & ^(^0 << 7)
b & mask(7)

@AndreasBackx , 1<<12 es más claro que 0b0001000000000000 porque no tengo que contar todos esos ceros. Es evidente que es una máscara porque 12 se encuentra entre 11 y 13 , o usa iota . Cuando se tiene que hacer coincidir un patrón arbitrario, por ejemplo, enmascarar bits de una palabra de instrucción, entonces hexadecimal es mejor porque un programador acostumbrado a tratar con bits puede leer 0xae y "ver" 10101110 en virtud de saber 0xa, diez, es 1010, mnemónico diez- diez, al igual que uno aprende tablas de multiplicar, 65 es ASCII A , etc. Hex es una representación más densa que es más fácil de analizar para el lector humano.

@ randall77 , ¿no son 0644, 02775, etc., un poco tediosos sin octal? Por eso todavía está dando vueltas.

@RalphCorderoy : sí, me parece que octal sobrevive por la única razón de construir un os.FileMode .
0664 = 6<<6 + 6<<3 + 4 , que no es demasiado tedioso. Sería mejor si os proporcionara constantes simbólicas para hacer esto más fácil, o al menos más claro.

Ya sabemos cómo evitar el problema de contar ceros: deberíamos admitir que 0b1e10 signifique 1 seguido de 10 ceros, en binario. Es cierto que esto funcionaría mejor si tuviéramos una forma de concatenar constantes binarias en lugar de agregarlas.

De hecho, hice el trabajo primero, ya que mi objetivo principal era piratear el compilador.

Excelente. Si desea algunas ideas sobre lugares para seguir pirateando el compilador mientras se discute esto, no dude en enviarme un correo electrónico: (nombre de usuario de github) @ gmail.

@RalphCorderoy 1 << 12 es más claro que 0b0001000000000000 porque no tengo que contar todos esos ceros.

Una solución a este problema sería permitir algún tipo de separación. Java permite guiones bajos en literales numéricos. Se ha discutido brevemente en el # 42, pero no hubo muchos argumentos en contra, si es que hubo algún comentario sobre ese tema en primer lugar.

Quizás también debería considerarse la solución de @ianlancetaylor .

Es evidente que es una máscara porque el 12 cae entre 11 y 13, o usa iota.

Lo siento, pero quizás este sea tu caso. Pero no para todos los demás.

Cuando se tiene que hacer coincidir un patrón arbitrario, por ejemplo, enmascarar bits de una palabra de instrucción, entonces hexadecimal es mejor porque un programador acostumbrado a tratar con bits puede leer 0xae y "ver" 10101110 en virtud de saber 0xa, diez, es 1010, mnemónico diez- diez, al igual que uno aprende tablas de multiplicar, 65 es ASCII A, etc.

Esto deja margen para el error en el código, como he dicho anteriormente y las propuestas hechas para otros idiomas que lo encontraron como una razón válida. También está asumiendo aquí que cada "programador" sabe el hechizo de la cabeza y ese no es el caso. Puede trabajar con mucho hardware, pero la mayoría de la gente no lo hace. Definitivamente, los principiantes preferirían los literales binarios sobre la representación hexadecimal.

Hex es una representación más densa que es más fácil de analizar para el lector humano.

¿Denso significa que es más limpio? No, no lo hace. La gente escribe frases de una sola línea todo el tiempo para cosas locas y la razón por la que son algo impresionantes es porque ese código es tan denso e ilegible que todos nos preguntamos qué brujería se esconde detrás del significado de cada carácter.

1 << 10 es mucho más claro que 0b1e10 .

Encuentro los literales binarios difíciles de leer. Muy a menudo, lo que necesita se redondea a segmentos de tres o cuatro bits, que son mucho más fáciles y menos propensos a errores de leer y escribir en octal o hexadecimal. Cuando las cosas no se redondean a límites tan uniformes , un cambio también es mucho más fácil de leer y escribir, y menos propenso a errores.

Alguna forma de concatenación haría que los literales binarios fueran más fáciles de leer y escribir, a costa de la inconsistencia. ¿Por qué se pueden concatenar literales binarios, pero ningún otro tipo de literales numéricos? ¿Por qué no hechizar? En este punto, esta discusión se vuelve ilimitada.

Personalmente, preferiría algún tipo de mecanismo de base genérico. No creo que los literales binarios aporten lo suficiente a la mesa (y solo escribo código de bajo nivel).

Además, estoy bastante seguro de que tuvimos esta discusión varias veces antes.

(Como nota al margen, la desaparición de octal ha sido muy exagerada. Octal es útil más allá de la configuración de modos de archivo. Ciertamente uso literales octales más de lo que usaría literales binarios).

Me sorprende un poco ver que se dan tantas opiniones personales como argumentos sobre un cambio de idioma. No estoy seguro de cómo cuantificar los comentarios relacionados con lo útil que lo encontraría personalmente.

Si por alguna razón los sentimientos personales tienen puntos de mérito, diré arbitrariamente que uso literales binarios en Java y puedo validar mi opinión al respecto diciendo que he estado programando durante 100 años y que tengo un automóvil.

A continuación, debatir si es más fácil usar el desplazamiento para definir máscaras es como argumentar que los calendarios gregorianos son más fáciles de usar que los calendarios chinos. El hecho de que le resulte más fácil de usar no significa que todos lo hagan. El hecho de que existan literales binarios en otros lenguajes probablemente debería ser una indicación de que alguien los encontró útiles, además de que el argumento cambiante no es un gran argumento, ya que es simplemente una alternativa.

Esto ha llegado antes. Hay una gran cantidad de trabajo involucrado en la implementación de esto, por lo que hacer que el compilador y los cambios en las especificaciones sean triviales. Pero hay muchas bibliotecas que también deberían ser consistentes (strconv, math / big, etc.).

Este es un argumento sólido en contra de esta propuesta y entiendo completamente la duda en hacer cambios que generen una cantidad significativa de trabajo.

En realidad, diría lo contrario. Hex es más compacto en muchos casos, sí, pero los literales binarios serían una representación exacta de "nivel de bits" y, por lo tanto, lo más legible posible.

Lo curioso de aprender binario es que tienes que leer y escribir binario y luego realizar operaciones matemáticas en él. Escribir en hexadecimal o decimal u octal o base64 (lul) puede ayudar indirectamente a aprender binario, pero escuché que solo aprender lo que quieres aprender directamente es útil (probablemente solo una opinión).

Personalmente, preferiría algún tipo de mecanismo de base genérico.

Ojalá todos los idiomas tuvieran esto en forma literal.

@ randall77 : Como se indicó en el número 151, hay varias razones para mantener octal. Sí, uno es la configuración de los modos de archivo, pero ese es el último importante. Los otros dos son el cambio de semántica que sería a un literal entero que comienza con 0, y la importancia del código de transferencia de seguridad de cualquier otro lenguaje similar a C, en el que las constantes octales tienen esta sintaxis. Es cierto que ninguno de estos es convincente, pero en conjunto cumplen con el estándar. De todos modos el tema está decidido, al menos para Go 1.

En cuanto a las constantes binarias, no creo que tengan su peso. Muy pocos programas se beneficiarían de ellos, e incluso entonces el beneficio es pequeño.

@robpike Sería seguro fallar al compilar cualquier cosa que pareciera una constante octal (comienza con 0 pero no "0").

Dejemos esto para Go 2.

¿Por qué esperar? No rompe nada.
El lunes 6 de marzo de 2017 a las 15:19, Russ Cox [email protected] escribió:

Dejemos esto para Go 2.

-
Estás recibiendo esto porque hiciste un comentario.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/golang/go/issues/19308#issuecomment-284535766 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/ABLfW7bN2NicSthvEvMeGEhqExg2et-qks5rjHhtgaJpZM4MNgUY
.

@DocMerlin , porque Go no es un lenguaje que sigue acumulando funciones solo porque puede hacerlo. Todos los cambios de idioma están básicamente en espera por ahora hasta que puedan evaluarse juntos como grupo, para que se vean, se sientan y funcionen juntos como un todo cohesionado. Por eso se etiqueta Go2.

@DocMerlin Me gusta agregar al comentario de

Estas también son muy pocas banderas, así que tenga en cuenta que esto definitivamente se suma cuando tiene más banderas.
ALGUNA_FLAG_D = 0b0000000001000000000000000000000

De un vistazo rápido, ¿es este 2 ^ 19 o 2 ^ 20? ¿Ves el problema?

Gracias @davecheney , me he puesto al día con el hilo. No había considerado que podría haber un esfuerzo masivo involucrado en hacer que la biblioteca estándar admita literales enteros binarios.

Es obvio que no hay casos de uso en los que una rutina que maneja la manipulación de bits en números enteros no se pueda expresar correctamente debido a la falta de literales binarios, y no se gana nada en términos de rendimiento expresando datos enteros en una base sobre otra.

Sin embargo, hay muchas situaciones de codificación binaria (códecs de video, compresión de datos, protocolos de red binarios, etc.) donde las máscaras de bits, las constantes binarias y otros datos de mapas de bits se pueden hacer más legibles en el código fuente si los datos se expresan en base 2.

Es una cuestión de legibilidad y estilo para las personas que manejan datos en mapas de bits.

La legibilidad y el estilo son las mismas razones por las que Go ha admitido la notación literal de entero octal desde el primer día. La inclusión de soporte para literales enteros octales es probablemente una decisión que tiene que ver con el manejo de permisos de archivos Unix. Es difícil imaginar en la actualidad muchos usos prácticos de la notación octal que no sean el soporte heredado de los permisos de estilo Unix y la legibilidad de estos datos en el código.

No obstante, el soporte octal es útil para mostrar que solo hay dos funciones simples en strconv encargadas del manejo de cadenas octales.

archive / tar / strconv.go: func (p * analizador) parseOctal (b [] byte) int64
archive / tar / strconv.go: func (f * formateador) formatOctal (b [] byte, x int64)

Para evaluar de manera muy aproximada el impacto del cambio de agregar soporte de literales binarios, un método posible es verificar la huella de código de soporte equivalente para octal, algo trivial porque octal se usa tan raramente que es fácil identificar los lugares y situaciones en las que base 8 esta apoyado.

En mi copia local en este momento, una búsqueda aproximada muestra que la mayoría de estas son operaciones de análisis y formato.

vxv @ vxs : / gosource $ grep -i -r octal * | wc -l
73
vxv @ vxs : / gosource $ grep -i -r octal * | grep "func" | wc -l
2

Es cierto que se trata de una búsqueda trivial y simple, pero las proporciones del problema no parecen presentar una tarea insuperable.

No hay problema. Para que conste, no tengo un perro en esta carrera, solo estoy aquí para arreglar los problemas. Depende de otros decidir el destino de esta propuesta para go 2

Sin embargo, hay muchas situaciones de codificación binaria (códecs de video, compresión de datos, protocolos de red binarios, etc.) donde las máscaras de bits, las constantes binarias y otros datos de mapas de bits se pueden hacer más legibles en el código fuente si los datos se expresan en base 2.

He usado todo lo anterior y nunca imaginé que la base 2 podría tener algún beneficio para estos. ¿Señalaría un ejemplo concreto para convencerme de lo contrario?

La legibilidad debería ser una de las principales razones para implementar literales binarios. Actualmente estoy escribiendo un motor que aprovecha las ventajas del posicionamiento de bits, y utilizo uint16, uint32 para varios casos de uso y cada segmento / sección de esas uints representa información diferente.

En ajedrez usamos movimientos codificados agregando banderas, desde y hasta la posición en un uint16. Sería bueno ver una implementación literal binaria para que el código pueda mostrar, solo por sí mismo, qué secciones se relacionan con qué información.

...
constexpr uint_fast16_t FLAG_SPECIAL1  {0b0010000000000000};
constexpr uint_fast16_t FLAG_SPECIAL0  {0b0001000000000000};
constexpr uint_fast16_t RANGE_FLAG     {0b1111000000000000};
constexpr uint_fast16_t RANGE_FROM     {0b0000111111000000};
constexpr uint_fast16_t RANGE_TO       {0b0000000000111111};

Este es mi ejemplo de código de C ++ 17. Sin embargo, en Go, se verá así:

const FlagSpecial1 uint16 = 8192
const FlagSpecial2 uint16 = 4096
const RangeFlag uint16 = 61440
const RangeFrom uint16 = 4032
const RangeTo uint16 = 63

Esencialmente útil para escribir código limpio y simple para cualquiera que trabaje con bits y máscaras.

¿No puedes conseguir un precompilador para esto y luego no tendrás que reescribir nada? Ya que después de todo es astético (a mis ojos).

Qué bit está configurado en (c ++)

constexpr uint_fast16_t FLAG_SPECIAL0  {0b0001000000000000};

vs

qué bit está configurado en (Ir)

const FlagSpecial0 = 0x10000

Probablemente no soy el único que puede decirlo inmediatamente en el último caso.

Con el enfoque 0b00 .. puede verlo, sin tener que conocer los números hexadecimales. Es más fácil de leer cuando tiene una lista grande de uint16. Entender que el bit establecido está en la posición 13, dado que el tamaño está en la lista, en el ejemplo que dio es más fácil que usar hexadecimal. 1<<13 , sería mucho mejor que hexadecimal y no tiene que buscar valores, solo puede mirarlo y saber qué bits están apuntados. Pero para un rango o varios conjuntos de bits, puede ser más fácil usar un literal binario.

Mirando los casos posteriores como 61440 Estoy impresionado de que pueda saberlo de inmediato, y cree que es más fácil saber qué bits se establecen usando decimales que un literal binario, pero no todos ven esto.

Pero simplemente ignoró los otros casos como 0b0000111111000000 que es 0xfe0 o 4064 en decimal. En mi opinión, es más limpio usar literal binario. 16 bits es un número mayor, pero mira los bytes:

0b11101010 frente a 0xea . Ni siquiera tiene que pensar en lo que está siendo el objetivo, solo lo sabe tan pronto como eche un vistazo.

@andersfylling , si está programando máscaras de bits, entonces realmente necesita poder leer hexadecimal: RangeFlag no sería 61440 sino 0xf000, lo que hace que sea obvio al instante que es el nibble superior de los 16 bits.

Para aquellos que piensan que tienen una visión novedosa sobre este tema, ¿pueden leer todos los comentarios desde la parte superior, tomando nota en particular de la referencia de Brad a la política NoMeToo, antes de despertar al resto de nuestro letargo?

El cambio hexadecimal y de bits lo hace todo por mí (más los permisos de archivo octal), pero me pregunto si aprender la manipulación de bits en C puede haber sido más fácil con literales enteros binarios. Me gusta cómo se ven los ejemplos anteriores en binario. Tal vez usaría esto para máscaras pequeñas o para cambiar máscaras pequeñas.

x := y & (0b101 << 8)

(editar: la mejor forma de ir es x := y & 0b101<<8 )

Hoy me encontré con esta falta de función. En mi caso de uso de ejemplo, estoy usando el campo de día de la semana entero de una fecha (0..6 para significar domingo ... sábado) y lo comparo con una máscara de bits de preferencia. Debido a que la fuente del entero es programática, no defino un conjunto de constantes para cada día de la semana (mi código no tiene ninguna razón para hablar sobre DOMINGO específicamente), por lo que la sintaxis 1 << 3 no es útil aquí. Sin embargo, quiero un valor predeterminado para la máscara de bits de preferencia, que sería quizás 0b0111110. Obviamente, es fácil escribir este valor predeterminado como decimal (126) o hexadecimal (0x7e), pero es considerablemente más claro escribirlo en binario.

Re: octal, tenga en cuenta que entre python2 y pyhon3, dejaron de admitir el formato 0110 y ahora requieren 0o110 en su lugar. Luego, hicieron backporting del análisis 0o110 a python2 sin dejar caer el formato anterior allí, lo que facilita el uso de la nueva sintaxis menos propensa a errores, sin romper la compatibilidad con la versión anterior. En python2, una cantidad sustancial de usuarios de Python habían terminado declarando accidentalmente números octales al pegar números decimales rellenos de 0, lo que generaba confusión. (Problema común: números de serie acolchados en longitud de una base de datos de piezas o números de factura acolchados en longitud). De hecho, una vez pasé media hora confusa debido a esto, tratando de averiguar por qué mi prueba unitaria "obviamente correcta" estaba fallando.

Por otro lado, nunca he necesitado soporte para constantes de lenguaje en una base abitraria. Tal vez alguien lo haya hecho, pero eso parece una pista falsa (y la sintaxis necesaria para respaldarlo parece bastante feo).

Otro ejemplo que me quemó fue la definición de direcciones en los protocolos integrados (I2C, SPI, CAN, etc.) donde a menudo hay una dirección definida como una constante binaria en la hoja de datos desplazada que tiene algún tipo de bit de lectura / escritura. como parte del valor. Convertirlos a hexadecimal agrega una capa más de traducción que el cerebro humano tiene que hacer, por lo tanto, una cosa más para cuestionar al depurar.

Hola @tapir , lea mi comentario anterior https://github.com/golang/go/issues/19308#issuecomment -352290337 especialmente https://github.com/golang/go/wiki/NoPlusOne como ahora se llama NoMeToo.

Aquí hay una contrapropuesta que permite la notación de base arbitraria al mismo costo (o menos): # 28256. Propongo una notación a la que he aludido directa o indirectamente en varias discusiones, pero nunca escrita formalmente. Por favor comente allí para obtener opiniones.

Ver # 28493 (propuesta independiente) discutiendo el uso de _ como separador entre dígitos.

Si está revisando esta discusión antigua / archivada para Go 2, le sugiero que mire octal al mismo tiempo. Obviamente, no puede eliminar la notación 0123 (por razones de compatibilidad, no sin un período de desactivación al menos), pero puede agregar 0o123 al mismo tiempo que agrega 0bXXX . Esto permitiría un conjunto más consistente de identificadores de base numérica, promoviendo la agradable uniformidad de sintaxis y expectativa del programador de Go.

Pero, por sí sola, la propuesta binaria aún valdría la pena.

¿ strconv.ParseInt admitiría la sintaxis 0b010 cuando base es 0?

@nathany Sí, si decidimos admitir el prefijo 0b en el idioma, también deberíamos

Quizás menos obvio es si ParseInt también debería filtrar _ separadores si aceptamos esto junto con # 28493. Sería fácil como una ruta separada (reemplace _ con ` ) but for error handling (e.g.; do we allow _` en cualquier lugar, o no) y el rendimiento podría necesitar manejarlo en el ParseInt (y todas las demás rutinas ParseXXX para números ).

¿Debería haber una propuesta / problema por separado para el literal octal 0o o es mejor mantenerlo junto con esto?

0o coincidiría con Swift y Rust. Podríamos investigar su razonamiento para preferir esta sintaxis.

Una razón por la que he visto preferir 0o sobre 0 es para evitar la ambigüedad con strconv.ParseInt("012", 0, 64) donde "012" podría ser una entrada del usuario. Sin embargo, no sé si esto es un gran problema en Go como en otros idiomas, ya que Atoi siempre usa base 10, y no hay argumentos predeterminados en Go, por lo que el programador debe solicitar explícitamente derivar la base del prefijo de cadena especificando 0 para la base.

No puedo decir que alguna vez haya necesitado usar _ en una cadena que se está analizando. De hecho, menos obvio.

@nathany Sugeriría un tema aparte. Estoy de acuerdo en que si decidimos permitir 0b , podría tener sentido permitir también 0o para mantener la coherencia (y luego podríamos querer que gofmt reescriba automáticamente 0 -prefix octals en 0o prefijo octales para que el primero pueda eliminarse gradualmente de la base del código). Pero esta propuesta trata sobre literales enteros binarios; sigamos así.

Mi pregunta original no recibió respuesta, así que volví a leer el hilo completo para ver por qué un hilo
con tantos pulgares arriba tiene tan poca discusión.

Hasta ahora, la propuesta solicita literales binarios por las siguientes razones:

otros idiomas los tienen

La propuesta detalla meticulosamente cómo los tienen otros idiomas y cómo otros están acostumbrados a ellos. ¿Ha sido esto una razón suficientemente buena antes?

son "más legibles"

Estoy en desacuerdo. Son un patrón cobarde de unos y ceros que no se pronuncian fácilmente sin un
conversión a base16.

  • Tu solo sabes

0b11101010 frente a 0xea. Ni siquiera tiene que pensar en lo que se dirige, simplemente
conócelo tan pronto como le eches un vistazo.

_El primer bit de orden inferior, el tercer bit de orden inferior y el quinto bit de orden inferior están desactivados, pero no el resto. Y hay [cuenta la cantidad total de bits dos veces para asegurarse de que el número sea correcto] ocho
bits en total.

Sé cuál es el patrón y probablemente lo recordaré durante unos segundos. ¿Cómo es ese conocimiento?
inherentemente útil?

  • Ir vs C ++

Algunos argumentos tergiversan su beneficio, quizás sin querer. En un ejemplo particular en
En este hilo, se publicó el siguiente fragmento comparando go y c ++.

constexpr uint_fast16_t FLAG_SPECIAL1  {0b0010000000000000};
constexpr uint_fast16_t FLAG_SPECIAL0  {0b0001000000000000};
constexpr uint_fast16_t RANGE_FLAG     {0b1111000000000000};
constexpr uint_fast16_t RANGE_FROM     {0b0000111111000000};
constexpr uint_fast16_t RANGE_TO       {0b0000000000111111};

This is my code example from C++17. In Go however, it will look like this:

const FlagSpecial1 uint16 = 8192
const FlagSpecial2 uint16 = 4096
const RangeFlag uint16 = 61440
const RangeFrom uint16 = 4032
const RangeTo uint16 = 63

El problema es que C ++ está meticulosamente alineado mientras que Go no está formateado, carece de un bloque const y usa incorrectamente decimal en lugar de hexadecimal (que no se puede convertir fácilmente a binario dividiendo cada dígito hexadecimal en cuatro binarios) .

const (
    FlagSpecial1 uint16 = 0x2000
    FlagSpecial2 uint16 = 0x1000
    RangeFlag    uint16 = 0xf000
    RangeFrom    uint16 = 0x0fc0
    RangeTo      uint16 = 0x003f
)

las especificaciones de los protocolos publican binario a veces

Otro ejemplo que me quemó fue la definición de direcciones en los protocolos integrados.
(I2C, SPI,> CAN, etc ...) donde a menudo hay una dirección definida como una constante binaria en el
hoja de datos desplazada> que tiene algún tipo de bit de lectura / escritura como parte del valor. Mudado
ellos a hexadecimal agrega una capa más de traducción que el cerebro humano tiene que hacer, por lo tanto, una más
cosa a cuestionar al depurar.

El problema es que el cerebro humano no debería estar haciendo esto por ti en primer lugar. |

Considere nuevamente su experiencia de depuración. Va a volcar literales enteros binarios a stderr o
y grep para ellos más tarde? ¿Compartirá estos números con sus colegas diciendo cada 1
y 0 en voz alta? Lo más probable es que los envíe y transmita en hexadecimal, y si eso es cierto, es
También es cierto que el código fuente debe expresar esos dígitos en hexadecimal para eliminar la necesidad
para que el cerebro humano (o programa) haga aún más trabajo para el lector.

Muchas especificaciones expresan 1010 para significar un flujo de bits que consta de esos estados ordenados. Esto no se corresponde con la noción de bytes de los literales enteros binarios, y seguramente quemará a alguien esperando
para implementar un lector de flujo de bits. (Preferiría implementar un lector de flujo de bits en la biblioteca estándar que admitir literales enteros binarios).

Hoy me encontré con esta falta de función. En mi caso de uso de ejemplo, estoy usando el día de la semana entero
campo de una fecha (0..6 para significar domingo ... sábado) y compararlo con una máscara de bits de preferencia.
Debido a que la fuente del número entero es programática, no defino un conjunto de constantes para cada día
de la semana (mi código no tiene ninguna razón para hablar sobre DOMINGO específicamente), así que 1 << 3 sintaxis
no es útil aquí. Sin embargo, quiero un valor predeterminado para la máscara de bits de preferencia, que sería
quizás 0b0111110. Obviamente, es fácil escribir este valor predeterminado como decimal (126) o hexadecimal (0x7e), pero
es considerablemente más claro escribirlo en binario.

Tendría los días de la semana como constantes no exportadas y construiría la máscara OR ing sus valores. No estoy de acuerdo con los literales enteros binarios que ayudarían a aclarar algo en esta situación.

@as Gracias por tu comentario. Ha sido grabado.

Claramente no necesitamos _necesitamos_ literales enteros binarios; tenemos una forma razonablemente cercana de expresar tales números usando literales hexadecimales (y lo he señalado en la publicación de mi

Quizás una mejor manera de pensar sobre este tema es si queremos poner Go a la par con la mayoría de los otros lenguajes de programación a este respecto y completar el conjunto de representaciones literales enteras soportando todas las bases relevantes (2, 8, 10, 16).

Esa es una pregunta que está separada del sentimiento personal sobre la utilidad de los literales binarios y puede ser más fácil de responder.

El cambio https://golang.org/cl/152338 menciona este problema: spec: add binary integer literals (tentative)

Consulte https://golang.org/cl/152338 para conocer los cambios de especificaciones pertinentes a esta propuesta (ignorando los separadores _ en este primer paso).

El cambio https://golang.org/cl/152377 menciona este problema: spec: permit underscores for grouping in numeric literals (tentative)

Estaba buscando un punto de referencia para varios algoritmos de clasificación donde pseudoaleatorio se estableció como 0xff & (i ^ 0xab) Si fuera 0b10101011 lugar de 0xab , sería más legible. Me sorprende que no haya literales binarios en Go, ni siquiera una propuesta ...

@andrewmed Esta _es_ la propuesta para literales enteros binarios.

Gracias

Publicamos una propuesta combinada para # 19308, # 12711, # 28493 y # 29008 en golang.org/design/19308-number-literals .

Tenga en cuenta que esta será la primera propuesta para seguir el proceso descrito en la publicación del blog: tendremos todo listo y registrado al comienzo del ciclo de Go 1.13 (1 de febrero), pasaremos los próximos tres meses usando esos características y solicitando comentarios basados ​​en el uso real, y luego, al comienzo de la congelación de la versión (1 de mayo), tomaremos la "decisión de lanzamiento" sobre si incluir el trabajo en Go 1.13 o no.

Gracias por tus comentarios y toda tu ayuda para mejorar Go.

Originalmente sugerido por @rsc : sería prudente desaprobar (pero aún admitir) 0X para hexadecimal, y luego no agregar 0B (innecesario) y 0O (innecesario, confuso y difícil de leer).

@robpike ... y haz que gofmt comience a cambiar 0X a 0x.

@josharian , sí, también

Pero para 0X -> 0x se podría hacer en gofmt, sí.

No tengo sentimientos fuertes sobre 0B vs 0b y 0O vs 0o (muchos editores de código escriben un cero con una barra que se ve diferente a una O mayúscula; personalmente siempre uso minúsculas).

Pero el punto principal de agregar estos nuevos formatos es ser compatible con otros lenguajes y aliviar el dolor de las personas que vienen de esos lenguajes, y quizás traducir código que viene de otros lugares. Derrotaría ese propósito si dichas personas o código usaran mayúsculas en estos prefijos y Go no pudiera digerir esos literales después de todo.

También noto que habrá un poco de inconsistencia con el exponente donde permitimos E y e (y recientemente P y p).

En resumen, si bien apoyo totalmente el sentimiento, rechazar el 0B en mayúsculas parece una diferencia gratuita que no ayuda a las personas acostumbradas a 0b en minúsculas de todos modos (que supongo que es una mayoría) y perjudica a los demás.

Por otro lado, hacer que gofmt realice el cambio automáticamente (o tal vez con -s) parece una buena idea.

Como desarrollador integrado que trabaja mucho con bits individuales y máscaras de bits, los literales binarios serían un cambio bienvenido. Los descubrí recientemente en (GC) C y me sorprendió gratamente.
por supuesto, casi cualquier persona puede entender razonablemente rápidamente 0x1 , 0x80 y 0x8000 . pero algo como 0x1c te hace hacer una pausa. Por supuesto, (7 << 2) es un poco mejor 0b00011100 es más legible y transmite el significado - tres bits contiguos 2 posiciones a la izquierda - más claramente.

El cambio https://golang.org/cl/157677 menciona este problema: cmd/compile: accept new Go2 number literals

El cambio https://golang.org/cl/159997 menciona este problema: go/scanner: accept new Go2 number literals

El cambio https://golang.org/cl/160018 menciona este problema: cmd/gofmt: test that Go 2 number literals can be formatted

El cambio https://golang.org/cl/160239 menciona este problema: go/constant: accept new Go2 number literals

El cambio https://golang.org/cl/160240 menciona este problema: go/types: add tests for new Go 2 number literals

El cambio https://golang.org/cl/160247 menciona este problema: fmt: scan new number syntax

El cambio https://golang.org/cl/160250 menciona este problema: math/big: add %#b and %O integer formats

El cambio https://golang.org/cl/160248 menciona este problema: text/template: accept new number syntax

El cambio https://golang.org/cl/160246 menciona este problema: fmt: format 0b, 0o prefixes in %#b and %O

El cambio https://golang.org/cl/160244 menciona este problema: strconv: add 0b, 0o integer prefixes in ParseInt, ParseUint

El cambio https://golang.org/cl/160184 menciona este problema: cmd/gofmt: normalize number prefixes and exponents

El cambio https://golang.org/cl/160478 menciona este problema: design/19308-number-literals: add note about gofmt

Como recordatorio, presentamos un nuevo proceso para estos cambios de idioma relacionados con Go 2 en nuestra publicación de blog blog.golang.org/go2-here-we-come. Vamos a aceptar tentativamente una propuesta, aterrizar cambios al comienzo de un ciclo, adquirir experiencia usándola y luego tomar la decisión de aceptación final tres meses después, en el congelamiento. Para Go 1.13, esto significaría realizar un cambio cuando el árbol abra en febrero y tomar la decisión final cuando el árbol se congele en mayo.

Vamos a aceptar tentativamente esta propuesta para Go 1.13 y planeamos aterrizar su implementación cuando se abra el árbol. El estado del problema para "aceptación provisional" se marcará como Propuesta aceptada, pero se dejará abierto y se marcará como hitos para el lanzamiento de Go (Go1.13 aquí). En la congelación revisaremos el problema y lo cerraremos si finalmente se acepta.

El cambio https://golang.org/cl/161098 menciona este problema: spec: document new Go2 number literals

El cambio https://golang.org/cl/161199 menciona este problema: text/scanner: accept new Go2 number literals

El cambio https://golang.org/cl/163079 menciona este problema: text/scanner: don't liberally consume (invalid) floats or underbars

El cambio https://golang.org/cl/173663 menciona este problema: unicode/utf8: use binary literals

El cambio https://golang.org/cl/174897 menciona este problema: cmd/compile: disable Go1.13 language features for -lang=go1.12 and below

Como recordatorio, presentamos un nuevo proceso para estos cambios de idioma relacionados con Go 2 en nuestra publicación de blog blog.golang.org/go2-here-we-come. El ciclo de desarrollo de Go 1.13 ha terminado y es hora de tomar la decisión final.

Los comentarios sobre los cambios literales de los números de Go 2 han sido muy positivos, con muy pocas voces negativas. Estos cambios modernizan y armonizan la sintaxis literal numérica de Go sin agregar una complejidad significativa al lenguaje: ahora existe una notación de prefijo uniforme para las tres bases numéricas no decimales comunes, que coincide con la notación utilizada en otros lenguajes de programación modernos. La introducción de literales de punto flotante hexadecimales aborda un problema para las personas que se preocupan por el código numérico. El sufijo “i” ahora se puede usar con cualquier número literal (no imaginario) para crear una constante imaginaria de manera uniforme. Y finalmente, los guiones bajos se pueden usar para dividir literales más largos en grupos de dígitos para mejorar la legibilidad.

Propuesta aceptada para Go 1.13. Cerrando porque los cambios han aterrizado.

- rsc para revisión de propuestas

El cambio https://golang.org/cl/189718 menciona este problema: compiler: support new numeric literal syntax

¿Fue útil esta página
0 / 5 - 0 calificaciones