Go: proposta: especificação: literais inteiros binários

Criado em 27 fev. 2017  ·  91Comentários  ·  Fonte: golang/go

Atualmente, Go suporta literais inteiros octais e hexadecimais, além dos literais decimais padrão que você esperaria. Em um esforço para completar este grupo, proponho adicionar literais inteiros binários também. Eles viriam na forma de um novo prefixo para literais inteiros: 0b ou 0B .

Exoneração de responsabilidade inicial

Este foi meu primeiro mergulho no código-fonte Go e principalmente uma experiência de aprendizado para eu começar a apresentar alterações e outras coisas. Dito isso, agradeço toda e qualquer crítica, comentário e sugestão.

O "Porquê": Técnica Anterior

Literais binários existem ou apareceram em linguagens convencionais também, incluindo:

Todos os casos acima se estabeleceram em uma convenção de usar 0b ou 0B para prefixar literais binários, sugerindo que esta também seria uma escolha bastante confortável e sensata para Go, evitando invenções desnecessárias e fornecendo similaridade para programadores vindos dessas outras linguagens mencionadas.

O "Porquê": Continuação

Consegui encontrar algumas discussões anteriores relacionadas a isso, embora isso tenha ocorrido depois de eu já ter implementado o recurso e ter mais a ver com a alteração da sintaxe octal do que especificamente relacionado a literais binários. Mas https://github.com/golang/go/issues/12711#issuecomment -142338246 de @griesemer menciona que "tanto o 'o' para octal e 'b' para notação binária também foram discutidos no design do Go. Simplesmente não é suficiente para o investimento. " No entanto, não vejo isso como um bom argumento contra adicionar algo tão simples à linguagem. Especialmente considerando o fato de que hoje em dia mais e mais linguagens têm adotado a sintaxe para literais binários, parece que as decisões de design de Go anteriores podem precisar ser analisadas sob uma nova luz.

Exemplo de uso

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

Implementação

Como afirmei que foi mais uma experiência de aprendizado para mim, já tenho alterações que implementam esse recurso pronto:

Especificação CL-37502 : especifica a sintaxe para literais inteiros binários
CL-37503 cmd / compilar / interno / sintaxe: verificar literais binários
CL-37504 go / scanner: digitalizar literais inteiros binários
CL- 37505 strconv: suporte para análise de literais inteiros binários
Teste CL-37506 : estenda int_lit com usos literais binários

FrozenDueToAge Go2 LanguageChange NeedsDecision Proposal Proposal-Accepted

Comentários muito úteis

Vejamos por que as linguagens mencionadas avançaram e adicionaram suporte para literais binários. Vamos começar com C ++ 14, pois é o primeiro da lista. Quais foram os pontos apresentados por James Dennett, então funcionário do Google?

O uso de um prefixo 0b / 0B para literais binários é uma extensão GCC existente (também compatível com Clang) e tem a mesma sintaxe do Java 7, Python e D.

Por que esse ponto específico beneficiaria Go?

Familiaridade com o idioma.

Muitos desenvolvedores mudam de linguagem de programação para linguagem de programação. Corrija-me se eu estiver errado, mas todos nós tentamos o que sabemos de um idioma em outro. De certa forma, você poderia dizer que a familiaridade de Go com C e C ++ atraiu aqueles tipos de desenvolvedores que queriam um recurso específico como GC, mas não gostavam de outras linguagens. Este é um dos motivos pelos quais a empresa em que estou estagiário optou por se mudar para a Go.

Além de desenvolvedores experientes, vamos dar uma olhada nos benefícios da familiaridade para desenvolvedores iniciantes. Vamos também pegar o caso de uso de sinalizadores que @eddieringle mencionou. Explicar para um iniciante completo como os sinalizadores funcionam é muito mais difícil quando você tem que explicar em octal ou hexadecimal, pois requer que a pessoa os aprenda também.

Por último, gostaria de acrescentar aqui que o propósito de cada linguagem (pelo menos é o que espero) é escrever um código limpo. E eu acho que é algo com que todos concordamos independentemente. Ao examinar o código de outra pessoa, fica imediatamente claro, sem qualquer explicação, que, ao se ter uma lista de constantes literais binárias, essas são sinalizações. Essa mesma coisa é muito menos direta ao usar hexadecimal ou octal. Abaixo está uma comparação.

// 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
)

Eu realmente acho que não é preciso pensar no fato de que as últimas constantes são usadas para sinalizadores. Também são muito poucos sinalizadores, portanto, lembre-se de que isso definitivamente aumenta quando há mais sinalizadores. A primeira constante 0x1E pode definitivamente virar algumas cabeças quando é declarada sem contexto. O uso de literais binários por si só pode indicar que uma variável pode ser usada como um sinalizador.

O referido PDF C ++ também se refere aos idiomas mencionados para suporte. Então, vamos olhar para eles a seguir. Eu encontrei a proposta (original?) De Derek Foster em 2009 para literais binários em JDK. Fonte

A primeira coisa que questiona, com a qual concordo totalmente, é por que há uma representação octal no JDK, mas não há representação binária no JDK. Nos últimos anos, nunca pensei comigo mesmo: "Oh, octais tornariam meu código mais limpo!" No entanto, isso se refere ao ponto anterior que fiz: familiaridade . No entanto, há uma coisa que acrescenta ao meu ponto anterior:

Quando os dados que estão sendo tratados são fundamentalmente orientados a bits, no entanto, usar hexadecimal para representar intervalos de bits requer um grau extra de tradução para o programador, e isso pode frequentemente se tornar uma fonte de erros. [...] então, um programador que codifica para essa especificação deve traduzir cada um desses valores de sua representação binária para hexadecimal. [...] Na maioria dos casos, os programadores fazem essas traduções em suas cabeças e ESPERAMOS que as acertem. no entanto, erros podem surgir facilmente e verificar novamente os resultados não é simples o suficiente para ser feito com frequência.

A notação hexadecimal e octal usada principalmente em hardware em vez de binária pode resultar em erros humanos. Na comparação que fiz anteriormente, verifiquei o que fiz com a minha cabeça, inserindo o que pensei ser octal no Google, o que confirmou as minhas respostas. Tenho certeza automática do meu caso quando escrevo em binário, mas não quando escrevo em hexadecimal ou octal. E não importa quantas vezes você faça isso por dia, fica mais difícil escrever código porque você tem que pensar na forma binária em sua cabeça e, enquanto faz isso, é possível cometer erros.

Para aprofundar a questão de por que existe uma notação octal, mas nenhuma notação binária, tenho outra pergunta a fazer, que também foi feita por Derek Foster, o autor da proposta literal binária para o JDK: "Por que Go escolheu usar o prefixo 0 para notações octais? " @griesemer comentou que não devemos precipitar-se ao implementar novos recursos:

Vamos esperar para ver o que as outras pessoas dizem antes de usar a arma. Obrigado.

Mas Go não se precipitou ao implementar a notação octal? Se seu argumento era "porque outras linguagens fazem isso", então por que esse argumento não pode ser usado para literais binários? Se não foi, qual foi a razão de o prefixo 0 para notações octais ter entrado na linguagem quando confunde as pessoas?

Alguém pode pensar incorretamente que "0b1" representava o mesmo valor que o número hexadecimal "0xB1". No entanto, observe que esse problema existe para octal / decimal há muitos anos (confusão entre "050" e "50") e não parece ser um grande problema.

- Derek Foster

Não parece haver mais pontos a favor dos literais binários porque é algo a que todos nos referimos em nossas cabeças. É por isso que sinto que as propostas para outras línguas foram breves como esta. No entanto, não é motivo para encerrá-lo tão rapidamente.

Todos 91 comentários

Isso já aconteceu antes. Há uma quantidade significativa de trabalho envolvida na implementação disso, tornando as alterações do compilador e das especificações triviais. Mas há muitas bibliotecas que também devem ser consistentes (strconv, math / big, etc.).

Se fizermos uma mudança nesta direção, ela deve ser mais completa e apoiar bases arbitrárias. Eu sou contra isso como está.

@griesemer Sim, as alterações que estou prestes a enviar também modificam strconv (no meu entendimento, na verdade são necessárias para apoiar essa alteração).

@griesemer Eu discordo, entretanto, que qualquer mudança deve suportar bases arbitrárias ou então nenhuma mudança deve ser feita. De acordo com a leitura anterior, parece que esse seria um bom objetivo para Go2; isso é simplesmente polir Go1 com a sintaxe que os desenvolvedores de outras linguagens podem esperar ao usar Go. (ou seja, Base-2 é um caso comum, provavelmente mais comum do que octal; base-14 ou sei lá o quê é menos).

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

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

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

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

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

No entanto, não vejo isso como um bom argumento contra adicionar algo tão simples à linguagem.

Também não é um argumento particularmente forte a favor de adicioná-los.

IMHO, você precisará expandir a seção "por que" explicando exatamente quais vantagens o suporte a literais binários trará para as pessoas que escrevem código go.

Não os acho particularmente úteis; hex é um formato muito mais legível e compacto para literais que possuem um "significado de nível de bit".

Você deu um 'exemplo de uso', mas não é muito convincente. Eu escreveria essas constantes usando 0xf s e deslocamentos para as outras.

@EddieRingle Esta proposta não foi amplamente discutida nem aceita. Por favor, não nos envie spam com análises de código. A Go Team tem o suficiente para fazer com um trabalho que é realmente importante.

É claro para todos que adicionar um recurso simples à linguagem é trivial. Também está claro que muitas pessoas gostariam desse recurso (eu mesmo teria gostado em algum momento). Mas, dito isso, só porque se pode, não é um argumento que se deva. Qualquer adição a um idioma, por menor e simples que seja, tem custos de longo prazo. Se aceitarmos isso, será ainda mais difícil no futuro ter um mecanismo mais geral e precisamos permanecer compatíveis com as versões anteriores.

Vamos esperar para ver o que as outras pessoas dizem antes de usar a arma. Obrigado.

Lembrete de nossa política proibida :

Opiniões sem conteúdo construtivo podem ser expressas usando as reações emoji do Github.

@ALTree

IMHO, você precisará expandir a seção "por que" explicando exatamente quais vantagens o suporte a literais binários trará para as pessoas que escrevem código go.

Não os acho particularmente úteis; hex é um formato muito mais legível e compacto para literais que têm um "significado de nível de bit", IMO.

Eu argumentaria o oposto, na verdade. Hex é mais compacto em muitos casos, sim, mas literais binários seriam uma representação exata de "nível de bit" e, portanto, tão legível quanto possível.

@griesemer

Esta proposta não foi amplamente discutida nem aceita. Por favor, não nos envie spam com análises de código. A Go Team tem o suficiente para fazer com um trabalho que é realmente importante.

Desculpas. Originalmente, era uma única alteração, mas como parece que a política do Go é quebrar os commits com base na área da base de código afetada, foi assim que acabei dividindo-os. Eu não sabia que o bot faria comentários individuais aqui para cada mudança. Eu não seria tão frio a ponto de chamá-lo de spam, nem quero dizer que qualquer esforço que eu coloquei no uso do meu tempo livre não seja importante.

Qualquer adição a um idioma, por menor e simples que seja, tem custos de longo prazo. Se aceitarmos isso, será ainda mais difícil no futuro ter um mecanismo mais geral e precisamos permanecer compatíveis com as versões anteriores.

Como foi mencionado antes, a rota de uso geral (que eu também preferiria) também encorajaria a depreciação / remoção da sintaxe octal existente (confusa), não? A sensação que tive foi de que a sintaxe de uso geral ( 2r0010 ou 2x0010 para base 2, por exemplo) foi uma invenção destinada ao Go2, onde alterações significativas seriam bem-vindas de qualquer maneira.

Pondo de lado um Go2 potencial, para abordar a afirmação de que "_se aceitarmos isso, será ainda mais difícil no futuro ter um mecanismo mais geral_": Eu simplesmente não vejo como isso é verdade. Adicionar o prefixo do literal binário seria ortogonal a uma sintaxe alternativa de uso geral, especialmente aquela que você descreveu em # 12711 (na verdade, essa sintaxe entra em conflito diretamente com os literais hexadecimais, mas não entraria com esta sintaxe literal binária proposta). Eles existiriam lado a lado, assim como a sintaxe de propósito geral faria com os literais octal, hexadecimal e decimal existentes.

Desculpas. Originalmente, era uma única alteração, mas como parece que a política do Go é quebrar os commits com base na área da base de código afetada, foi assim que acabei dividindo-os. Eu não sabia que o bot faria comentários individuais aqui para cada mudança. Eu não seria tão frio a ponto de chamá-lo de spam, nem quero dizer que qualquer esforço que eu coloquei no uso do meu tempo livre não seja importante.

Não é apenas que o bot envia uma mensagem sobre CLs, é que cada CL enviada é uma solicitação para um revisor Go passar um tempo revisando-a.

A sintaxe 0b é boa porque é familiar, mas se o verdadeiro objetivo for simplesmente adicionar literais binários à linguagem, eu preferiria muito mais a solução genérica à familiar.

Existe algum motivo técnico para a opção genérica não poder ser implementada antes do 2.0? Tive vários casos recentemente em que literais binários teriam sido preferidos a hexadecimais e seria bom ter essa opção em 1.9 ou 1.10 em vez de esperar (possivelmente muitos anos) até 2.0.

@wedow Acho que ajudaria ver casos reais específicos em que literais binários são úteis. Compartilhe os casos em que literais binários seriam úteis. Obrigado.

Não vejo "deve apoiar bases arbitrárias" como uma objeção válida. Ele adiciona complexidade / custo com pouco ou nenhum benefício adicional. Ao longo de todos os anos que estive hackeando, as bases que seriam úteis que ouvi de pessoas que desejam usar são 2, 8, 10, 12 e 16 e possivelmente 64 (afinal, temos codificação base64) .

Vejamos por que as linguagens mencionadas avançaram e adicionaram suporte para literais binários. Vamos começar com C ++ 14, pois é o primeiro da lista. Quais foram os pontos apresentados por James Dennett, então funcionário do Google?

O uso de um prefixo 0b / 0B para literais binários é uma extensão GCC existente (também compatível com Clang) e tem a mesma sintaxe do Java 7, Python e D.

Por que esse ponto específico beneficiaria Go?

Familiaridade com o idioma.

Muitos desenvolvedores mudam de linguagem de programação para linguagem de programação. Corrija-me se eu estiver errado, mas todos nós tentamos o que sabemos de um idioma em outro. De certa forma, você poderia dizer que a familiaridade de Go com C e C ++ atraiu aqueles tipos de desenvolvedores que queriam um recurso específico como GC, mas não gostavam de outras linguagens. Este é um dos motivos pelos quais a empresa em que estou estagiário optou por se mudar para a Go.

Além de desenvolvedores experientes, vamos dar uma olhada nos benefícios da familiaridade para desenvolvedores iniciantes. Vamos também pegar o caso de uso de sinalizadores que @eddieringle mencionou. Explicar para um iniciante completo como os sinalizadores funcionam é muito mais difícil quando você tem que explicar em octal ou hexadecimal, pois requer que a pessoa os aprenda também.

Por último, gostaria de acrescentar aqui que o propósito de cada linguagem (pelo menos é o que espero) é escrever um código limpo. E eu acho que é algo com que todos concordamos independentemente. Ao examinar o código de outra pessoa, fica imediatamente claro, sem qualquer explicação, que, ao se ter uma lista de constantes literais binárias, essas são sinalizações. Essa mesma coisa é muito menos direta ao usar hexadecimal ou octal. Abaixo está uma comparação.

// 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
)

Eu realmente acho que não é preciso pensar no fato de que as últimas constantes são usadas para sinalizadores. Também são muito poucos sinalizadores, portanto, lembre-se de que isso definitivamente aumenta quando há mais sinalizadores. A primeira constante 0x1E pode definitivamente virar algumas cabeças quando é declarada sem contexto. O uso de literais binários por si só pode indicar que uma variável pode ser usada como um sinalizador.

O referido PDF C ++ também se refere aos idiomas mencionados para suporte. Então, vamos olhar para eles a seguir. Eu encontrei a proposta (original?) De Derek Foster em 2009 para literais binários em JDK. Fonte

A primeira coisa que questiona, com a qual concordo totalmente, é por que há uma representação octal no JDK, mas não há representação binária no JDK. Nos últimos anos, nunca pensei comigo mesmo: "Oh, octais tornariam meu código mais limpo!" No entanto, isso se refere ao ponto anterior que fiz: familiaridade . No entanto, há uma coisa que acrescenta ao meu ponto anterior:

Quando os dados que estão sendo tratados são fundamentalmente orientados a bits, no entanto, usar hexadecimal para representar intervalos de bits requer um grau extra de tradução para o programador, e isso pode frequentemente se tornar uma fonte de erros. [...] então, um programador que codifica para essa especificação deve traduzir cada um desses valores de sua representação binária para hexadecimal. [...] Na maioria dos casos, os programadores fazem essas traduções em suas cabeças e ESPERAMOS que as acertem. no entanto, erros podem surgir facilmente e verificar novamente os resultados não é simples o suficiente para ser feito com frequência.

A notação hexadecimal e octal usada principalmente em hardware em vez de binária pode resultar em erros humanos. Na comparação que fiz anteriormente, verifiquei o que fiz com a minha cabeça, inserindo o que pensei ser octal no Google, o que confirmou as minhas respostas. Tenho certeza automática do meu caso quando escrevo em binário, mas não quando escrevo em hexadecimal ou octal. E não importa quantas vezes você faça isso por dia, fica mais difícil escrever código porque você tem que pensar na forma binária em sua cabeça e, enquanto faz isso, é possível cometer erros.

Para aprofundar a questão de por que existe uma notação octal, mas nenhuma notação binária, tenho outra pergunta a fazer, que também foi feita por Derek Foster, o autor da proposta literal binária para o JDK: "Por que Go escolheu usar o prefixo 0 para notações octais? " @griesemer comentou que não devemos precipitar-se ao implementar novos recursos:

Vamos esperar para ver o que as outras pessoas dizem antes de usar a arma. Obrigado.

Mas Go não se precipitou ao implementar a notação octal? Se seu argumento era "porque outras linguagens fazem isso", então por que esse argumento não pode ser usado para literais binários? Se não foi, qual foi a razão de o prefixo 0 para notações octais ter entrado na linguagem quando confunde as pessoas?

Alguém pode pensar incorretamente que "0b1" representava o mesmo valor que o número hexadecimal "0xB1". No entanto, observe que esse problema existe para octal / decimal há muitos anos (confusão entre "050" e "50") e não parece ser um grande problema.

- Derek Foster

Não parece haver mais pontos a favor dos literais binários porque é algo a que todos nos referimos em nossas cabeças. É por isso que sinto que as propostas para outras línguas foram breves como esta. No entanto, não é motivo para encerrá-lo tão rapidamente.

Aqui está outra opção, que me parece mais clara do que qualquer uma das constantes inteiras.

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

(E a máscara não deveria ser 0xf, não 0x1e?)

Sou ligeiramente contra a adição de constantes binárias, pelo menos no Go 1. No entanto, eu seria a favor de adicioná-las ao Go 2. A razão para a diferença é que se por alguma razão alguém está preso no Go 1.8, quando o Go 1.9 sai com constantes binárias, se uma das importações (transitivas) do código dessa pessoa usa constantes binárias, então eles não podem mais construir seus projeto usando Go 1.8. Eles teriam que vender ou atualizar. Há um custo definido para adicionar um recurso incompatível com versões anteriores que deve pesar contra sua utilidade.

Eu concordo que não vejo nenhuma necessidade de bases que não estejam em {2,8,10,16}. O caso para octal parece particularmente instável, eu estaria por remover octal no Go 2.

@ randall77 Eu discordo que a mudança parece mais limpa. Na minha cabeça, ainda estou representando-os como números binários e provavelmente sempre o farei. Seria mais fácil remover aquele cálculo que faço na minha cabeça.

(E a máscara não deveria ser 0xf, não 0x1e?)

O nome MASK foi simplesmente retirado da proposta JDK e não está realmente de acordo com as outras constantes. Mas mostra que 0x1E e hexadecimais já causam confusão.

Eu posso entender o que você está tentando fazer ao querer movê-lo para Go 2. Mas eu discordo que devemos ter que apoiar projetos que fazem downgrade de sua versão Go de 1.9 para 1.8. Isso tornaria as mudanças de idiomas um pesadelo. No entanto, não sei como Go encara isso, seria mais sábio seguir a compatibilidade que Go tem em mente.

Apoio de todo o coração a sua posição sobre a remoção do octal no Go 2.

Acabei de reler meu comentário anterior (especificamente, "The Go Team tem o suficiente para fazer com um trabalho que é realmente importante."). Quero me desculpar por essa declaração, que foi uma formulação um tanto ofensiva do que eu realmente quis dizer. Então, deixe-me tentar novamente, elaborando um pouco mais e, com sorte, encontrando o tom certo desta vez:

Agradecemos propostas bem fundamentadas e, se necessário, acompanhadas de implementações de protótipos. Dito isso, o processo de proposta Go é leve de propósito e nenhum trabalho extra é exigido pelo proponente, a menos que seja solicitado ou necessário para entender a proposta. O envio de listas de alterações que não são solicitadas e / ou não corrigem um problema é contraproducente, pois alguém terá que perder tempo e olhar para elas (nem que seja para adiá-las ou fechá-las). Uma abordagem melhor, se alguém quiser criar um protótipo / escrever o código com antecedência, é vincular as alterações em outro lugar (por exemplo, um commit privado do GitHub). Isso deixará a equipe de Go e colaboradores externos com a escolha: eles podem decidir olhar para aquele código se quiserem, ou então focar em itens de prioridade mais alta. Obrigado.

@griesemer Gotcha, eu entendo e isso faz sentido. Presumi que a equipe Go tratava seu Gerrit como o AOSP trata o deles, e imaginei que minhas mudanças poderiam existir lá enquanto isso era discutido. Vincular a um branch aqui no GitHub dá menos trabalho de qualquer maneira, então é uma situação em que todos ganham, eu acho. :)

Na verdade, eu fiz o trabalho primeiro, já que meu objetivo principal era hackear o compilador. Foi depois do fato que decidi apresentá-lo como uma proposta.

@AndreasBackx O 0 líder para octal em Go foi discutido na edição # 151. Veja também # 12711.

Ao definir constantes de 1 conjunto de bits, o deslocamento é mais legível do que 0b00001000..00 pela simples razão de que na versão de deslocamento você não precisa contar muitos zeros na tela apenas para entender qual bit está definido ; você acabou de ler o valor de deslocamento.

0b100000000000000000000000 vs 1 << 23

No que diz respeito ao uso no mundo real, um método comum de codificação de inteiros de comprimento variável é usar o bit alto para "ler mais". Eu tive que usá-lo para extrair git packfiles. Aqui está o código para extrair os bits inferiores em várias bases:

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

Eu pessoalmente acho que a versão binária mostra mais claramente a intenção.

Você ainda tem a opção de mudança mencionada anteriormente
Se você acha que não é legível, use uma função auxiliar

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

@AndreasBackx , 1<<12 é mais claro do que 0b0001000000000000 porque não tenho que contar todos aqueles zeros. É aparente que é uma máscara porque 12 fica entre 11 e 13 , ou usa iota . Ao ter que corresponder a um padrão arbitrário, por exemplo, mascarar bits de uma palavra de instrução, então hex é melhor porque um programador acostumado a lidar com bits pode ler 0xae e "ver" 10101110 em virtude de saber 0xa, dez, é 1010, dez mnemônico- dez, assim como se aprende a tabuada, 65 é ASCII A , etc. Hex é uma representação mais densa que é mais fácil de analisar para o leitor humano.

@ randall77 , 0644, 02775, etc. não são um pouco enfadonhos sem octal? É por isso que ainda está acontecendo.

@RalphCorderoy : sim, parece-me que o octal sobrevive pela única razão de construir um os.FileMode .
0664 = 6<<6 + 6<<3 + 4 , o que não é muito tedioso. Seria melhor se os fornecesse constantes simbólicas para tornar isso mais fácil, ou pelo menos mais claro.

Já sabemos como evitar o problema da contagem de zeros: devemos apoiar 0b1e10 para significar 1 seguido por 10 zeros, em binário. É certo que isso funcionaria melhor se tivéssemos uma maneira de concatenar constantes binárias em vez de adicioná-las.

Na verdade, eu fiz o trabalho primeiro, já que meu objetivo principal era hackear o compilador.

Excelente. Se você quiser algumas idéias de lugares para continuar a hackear o compilador enquanto isso é discutido, sinta-se à vontade para me mandar um e-mail - (nome de usuário do github) @ gmail.

@RalphCorderoy 1 << 12 é mais claro do que 0b0001000000000000 porque não preciso contar todos aqueles zeros.

Uma solução para esse problema seria permitir algum tipo de separação. Java permite sublinhados em literais numéricos. Isso foi discutido brevemente no nº 42, mas não havia muitos argumentos contra isso, se é que havia algum comentário sobre o assunto em primeiro lugar.

A solução de @ianlancetaylor também deve ser considerada.

É aparente que é uma máscara porque o 12 está entre 11 e 13, ou usa iota.

Sinto muito, mas talvez seja o seu caso. Mas não para todos os outros.

Ao ter que corresponder a um padrão arbitrário, por exemplo, mascarar bits de uma palavra de instrução, então hex é melhor porque um programador acostumado a lidar com bits pode ler 0xae e "ver" 10101110 em virtude de saber 0xa, dez, é 1010, dez mnemônico- dez, assim como se aprende a tabuada, 65 é ASCII A, etc.

Isso deixa margem para erro no código, como foi anteriormente declarado por mim e propostas feitas para outras linguagens que consideraram um motivo válido. Você também está assumindo aqui que todo "programador" conhece hexa de início e esse não é o caso. Você pode trabalhar com muito hardware, mas a maioria das pessoas não. Definitivamente, os iniciantes prefeririam os literais binários à representação hexadecimal.

Hex é uma representação mais densa e mais fácil de analisar para o leitor humano.

Denso significa que é mais limpo? Não, não faz. As pessoas escrevem frases curtas o tempo todo para coisas malucas e a razão disso serem impressionantes é porque o código é tão denso e ilegível que todos nós nos perguntamos que bruxaria está escondida por trás do significado de cada personagem.

1 << 10 é muito mais claro do que 0b1e10 .

Acho que os literais binários são difíceis de ler. Muitas vezes, o que você precisa arredonda até três ou quatro segmentos de bits, que são muito mais fáceis e menos propensos a erros de ler e escrever em octal ou hexadecimal. Quando as coisas não chegam a limites

Alguma forma de concatenação tornaria os literais binários mais fáceis de ler e escrever, ao custo de inconsistência. Por que os literais binários podem ser concatenados, mas nenhum outro tipo de literais numéricos? Por que não hex? Nesse ponto, essa discussão torna-se ilimitada.

Pessoalmente, eu preferiria algum tipo de mecanismo genérico de raiz. Não acho que literais binários tragam o suficiente (e eu apenas escrevo código de baixo nível).

Além disso, tenho certeza de que já discutimos isso várias vezes antes.

(Como uma observação lateral, o fim do octal foi muito exagerado. O octal é útil além de definir modos de arquivo. Eu certamente uso literais octais mais do que usaria literais binários.)

É um pouco surpreendente para mim ver tantas opiniões pessoais sendo dadas como argumentos sobre uma mudança para um idioma. Não tenho certeza de como quantificar os comentários relacionados à utilidade que você consideraria pessoalmente.

Se por algum motivo os sentimentos pessoais têm pontos de mérito, direi arbitrariamente que uso literais binários em Java e posso validar minha opinião sobre isso dizendo que tenho programado por 100 anos e tenho um carro.

Em seguida, debater se é mais fácil usar a mudança para definir máscaras é como argumentar que os calendários gregorianos são mais fáceis de usar do que os calendários chineses. Só porque você acha que é mais fácil de usar, não significa que todos achem. O fato de que literais binários existem em outras linguagens provavelmente deve ser uma indicação de que alguém os considerou úteis, promovendo que o argumento variável não é muito um argumento, pois é simplesmente uma alternativa.

Isso já aconteceu antes. Há uma quantidade significativa de trabalho envolvida na implementação disso, tornando as alterações do compilador e das especificações triviais. Mas há muitas bibliotecas que também devem ser consistentes (strconv, math / big, etc.).

Este é um argumento sólido contra esta proposta e eu compreenderia completamente a hesitação em fazer mudanças que criem uma quantidade significativa de trabalho.

Eu argumentaria o oposto, na verdade. Hex é mais compacto em muitos casos, sim, mas literais binários seriam uma representação exata de "nível de bit" e, portanto, tão legível quanto possível.

O engraçado sobre aprender binário é que você tem que realmente ler e escrever binário e, em seguida, realizar cálculos matemáticos nele. Escrever em hexadecimal ou decimal ou octal ou base64 (lul) pode auxiliar indiretamente no aprendizado de binário, mas ouvi dizer que apenas aprender o que você deseja aprender diretamente é útil (provavelmente apenas uma opinião, no entanto).

Pessoalmente, eu preferiria algum tipo de mecanismo genérico de raiz.

Eu gostaria que todas as línguas tivessem isso de forma literal.

@ randall77 : Como afirma o nº 151, há várias razões para manter octal. Sim, um é a configuração dos modos de arquivo, mas esse é o último importante. Os outros dois são a mudança de semântica que seria para um literal inteiro que começa com 0, e a importância do código de portabilidade de segurança de todas as outras linguagens do tipo C, nas quais constantes octais têm essa sintaxe. É verdade que nenhum desses itens é atraente, mas, em conjunto, eles alcançam o padrão. De qualquer forma, a questão está decidida, pelo menos para Go 1.

Quanto às constantes binárias, não acho que tenham seu peso. Muito poucos programas se beneficiariam com eles e, mesmo assim, o benefício é pequeno.

@robpike Seria seguro apenas falhar ao compilar qualquer coisa que se parecesse com uma constante octal (começa com 0 mas não "0").

Vamos deixar isso para Go 2.

Porque esperar? Não quebra nada.
Na segunda-feira, 6 de março de 2017 às 15:19, Russ Cox [email protected] escreveu:

Vamos deixar isso para Go 2.

-
Você está recebendo isto porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/golang/go/issues/19308#issuecomment-284535766 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/ABLfW7bN2NicSthvEvMeGEhqExg2et-qks5rjHhtgaJpZM4MNgUY
.

@DocMerlin , porque Go não é uma linguagem que continua agregando recursos apenas porque pode. Todas as mudanças de linguagem estão basicamente em espera por enquanto até que possam ser avaliadas juntos como um grupo, para que pareçam, sintam-se e trabalhem juntos como um todo coeso. É por isso que é rotulado como Go2.

@DocMerlin Gosto de acrescentar ao comentário de @bradfitz que fizemos exceções no passado quando havia necessidades urgentes. Claramente não há necessidade urgente aqui.

Também são muito poucos sinalizadores, portanto, lembre-se de que isso definitivamente aumenta quando há mais sinalizadores.
SOME_FLAG_D = 0b0000000001000000000000000000000

Resumindo, é 2 ^ 19 ou 2 ^ 20? Veja o problema?

Obrigado @davecheney ,

É óbvio que não há casos de uso em que uma rotina que lida com a manipulação de bits em inteiros não pode ser expressa corretamente devido à falta de literais binários, e nada é ganho em termos de desempenho expressando dados inteiros em uma base sobre a outra.

No entanto, existem muitas situações de codificação binária (codecs de vídeo, compressão de dados, protocolos de rede binários, etc.) onde máscaras de bits, constantes binárias e outros dados de bitmap podem ser tornados mais legíveis no código-fonte se os dados forem expressos na base 2.

É uma questão de legibilidade e estilo para pessoas que lidam com dados de bitmap.

Legibilidade e estilo são os mesmos motivos pelos quais a notação literal de inteiro octal foi suportada pelo Go no primeiro dia. A inclusão de suporte para literais inteiros octais é provavelmente uma decisão que tem a ver com o tratamento de permissões de arquivo Unix. É difícil imaginar hoje em dia muitos usos práticos da notação octal além do suporte legado de permissões de estilo Unix e a legibilidade desses dados no código.

Mesmo assim, o suporte octal é útil para mostrar que existem apenas duas funções simples em strconv encarregadas do manuseio de cordas octais.

arquivo / tar / strconv.go: func (p * parser) parseOctal (b [] byte) int64
arquivo / tar / strconv.go: func (f * formatador) formatOctal (b [] byte, x int64)

Para avaliar aproximadamente o impacto da mudança da adição de suporte de literais binários, um método possível é verificar a pegada do código de suporte equivalente para octal, uma coisa trivial porque o octal é tão raramente usado que é fácil identificar os lugares e situações em que base 8 é suportado.

Na minha cópia local agora, uma pesquisa aproximada mostra que a maioria dessas são operações de análise e formatação.

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

Admito que se trata de uma busca trivial e simplória, mas as proporções do problema não parecem apresentar uma tarefa intransponível.

Sem problemas. Só para constar, não tenho um cachorro nesta corrida, estou aqui apenas para cuidar dos problemas. Cabe a outros decidir sobre o destino desta proposta para go 2

No entanto, existem muitas situações de codificação binária (codecs de vídeo, compressão de dados, protocolos de rede binários, etc.) onde máscaras de bits, constantes binárias e outros dados de bitmap podem ser tornados mais legíveis no código-fonte se os dados forem expressos na base 2.

Usei todos os itens acima e nunca imaginei que a base 2 pudesse ter algum benefício para eles. Você indicaria um exemplo concreto para me convencer do contrário?

A legibilidade deve ser o principal motivo para a implementação de literais binários. No momento, estou escrevendo um mecanismo que tira vantagens do posicionamento de bits e uso uint16, uint32 para vários casos de uso e cada fatia / seção desses uints representa informações diferentes.

No xadrez, usamos movimentos codificados adicionando bandeiras, de e para a posição em um uint16. Seria bom ver uma implementação literal binária para que o código pudesse mostrar, apenas por si mesmo, quais seções se relacionam a quais informações.

...
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 é meu exemplo de código do C ++ 17. No entanto, em Go, será semelhante a este:

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

Essencialmente útil para escrever código limpo e simples para qualquer pessoa que trabalhe com bits e máscaras.

Não é possível ir buscar um pré-compilador para isso e então você não terá que reescrever nada? Afinal é astético (aos meus olhos).

Qual bit está definido em (c ++)

constexpr uint_fast16_t FLAG_SPECIAL0  {0b0001000000000000};

vs

qual bit está definido em (Go)

const FlagSpecial0 = 0x10000

Provavelmente não sou o único que pode dizer imediatamente, apenas no último caso.

Com a abordagem 0b00 .. você pode ver isso, sem precisar saber os números hexadecimais. É mais fácil de ler quando você tem uma grande lista de uint16. Entender que o bit definido está na posição 13, já que o tamanho está listado, no exemplo que você deu é mais fácil do que usar hex. 1<<13 , seria muito melhor do que hex, assim como você não precisa procurar valores, você pode apenas olhar para ele e saber quais bits são direcionados. Mas para um intervalo ou conjuntos de bits múltiplos, pode ser mais fácil usar apenas um literal binário.

Olhando para os casos posteriores, como 61440 , estou impressionado que você possa dizer imediatamente, e você acha que é mais fácil saber quais bits são definidos usando decimais do que um literal binário, mas nem todo mundo vê isso.

Mas você simplesmente ignorou os outros casos, como 0b0000111111000000 que é 0xfe0 ou 4064 em decimal. Na minha opinião, isso é mais limpo usando literal binário. 16 bits é um número maior, mas observe os bytes:

0b11101010 vs 0xea . Você nem mesmo precisa pensar no que está sendo direcionado, você só sabe disso assim que der uma olhada.

@andersfylling , Se você está programando máscaras de bits, então você realmente precisa ser capaz de ler hex: RangeFlag não seria 61440, mas 0xf000, o que torna imediatamente óbvio que é o nibble superior dos 16 bits.

Para aqueles que pensam ter uma visão nova sobre este assunto, por favor, leia todos os comentários do início, observando especialmente a referência de Brad à política NoMeToo, antes de acordar o resto de nós de nosso sono.

Hex e bit shifting fazem tudo para mim (mais as permissões de arquivo octal), mas estou me perguntando se aprender a manipulação de bits em C pode ter sido mais fácil com literais inteiros binários. Eu gosto de como os exemplos acima parecem em binário. Talvez eu use isso para pequenas máscaras ou para mudar pequenas máscaras.

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

(editar: o melhor caminho para ir é x := y & 0b101<<8 )

Acabei de encontrar essa falta de recurso hoje. No meu caso de uso de exemplo, estou usando o campo inteiro de dia da semana de uma data (0..6 para significar domingo .. sábado) e comparando-o com uma máscara de bits de preferência. Como a fonte do inteiro é programática, não defino um conjunto de constantes para cada dia da semana (meu código não tem motivo para falar especificamente sobre DOMINGO), então a sintaxe 1 << 3 não é útil aqui. No entanto, quero um valor padrão para a máscara de bits de preferência, que talvez seja 0b0111110. Obviamente, é fácil escrever esse padrão como decimal (126) ou hex (0x7e), mas é consideravelmente mais claro escrevê-lo em binário.

Re: octal, observe que entre python2 e pyhon3, eles abandonaram o suporte para o formato 0110 e agora exigem 0o110. Em seguida, eles fizeram backport da análise 0o110 para python2 sem descartar o formato antigo lá, tornando mais fácil começar a usar a nova sintaxe menos sujeita a erros, sem quebrar a compatibilidade com a versão anterior. Em python2, um número substancial de usuários de python acabou declarando acidentalmente números octais ao colar números decimais com zero, levando à confusão. (Problema comum: números de série preenchidos de um banco de dados de peças ou números de faturas preenchidos.) Na verdade, certa vez, passei uma meia hora confusa por causa disso, tentando descobrir por que meu teste de unidade "obviamente correto" estava falhando.

Por outro lado, nunca precisei de suporte para constantes de linguagem em um radical abitrário. Talvez alguém tenha, mas isso parece uma pista falsa (e a sintaxe necessária para dar suporte parece que seria muito feia).

Outro exemplo que acabou de me queimar foi definir endereços nos protocolos embutidos (I2C, SPI, CAN, etc ...) onde muitas vezes há um endereço definido como uma constante binária na planilha de dados deslocada que tem algum tipo de bit de leitura / gravação como parte do valor. Convertê-los em hexadecimal adiciona mais uma camada de tradução que o cérebro humano precisa fazer, portanto, mais uma coisa a ser questionada durante a depuração.

Olá @tapir , por favor leia meu comentário anterior https://github.com/golang/go/issues/19308#issuecomment -352290337 especialmente https://github.com/golang/go/wiki/NoPlusOne como NoMeToo agora é chamado.

Aqui está uma contraproposta que permite a notação de raiz arbitrária com aproximadamente o mesmo (ou menos) custo: # 28256. Proponho uma notação à qual aludi direta ou indiretamente em várias discussões, mas nunca formalmente escrita. Por favor, comente lá para opiniões.

Veja # 28493 (proposta independente) discutindo o uso de _ como separador entre dígitos.

Se você estiver revisitando essa discussão antiga / engavetada para o Go 2, sugiro examinar o octal ao mesmo tempo. Obviamente, você não pode remover a notação 0123 (por razões de compatibilidade - não sem um período de depreciação, pelo menos), mas você pode adicionar 0o123 ao mesmo tempo que adiciona 0bXXX . Isso permitiria um conjunto mais consistente de identificadores de base numérica, promovendo a boa uniformidade de sintaxe do Go e a expectativa do programador.

Mas, por si só, a proposta binária ainda valeria a pena.

strconv.ParseInt suportaria a sintaxe 0b010 quando base fosse 0?

@nathany Sim, se decidirmos oferecer suporte ao prefixo 0b na linguagem, devemos também oferecer suporte na biblioteca. Por exemplo, o compilador atualmente depende do método SetString de math / big.Int para converter literais constantes em big.Ints - portanto, seria de se esperar que SetString (e amigos, como strconv.ParseInt) entendessem 0b também.

Talvez menos óbvio seja se o ParseInt também deve filtrar os separadores _ se aceitarmos isso junto com # 28493. Seria fácil como um caminho separado (substitua _ por ` ) but for error handling (e.g.; do we allow _` em qualquer lugar, ou não) e o desempenho que podemos precisar para lidar com isso no ParseInt (e todas as outras rotinas do ParseXXX para números )

Deve haver uma proposta / emissão separada para o literal 0o octal ou é melhor mantê-la junto com isso?

0o corresponderia a Swift e Rust. Poderíamos examinar seu raciocínio para preferir essa sintaxe.

Uma razão para preferir 0o vez de 0 é evitar ambigüidade com strconv.ParseInt("012", 0, 64) onde "012" poderia ser uma entrada do usuário. No entanto, não sei se isso é um grande problema em Go como em outras linguagens, sendo que Atoi sempre usa base 10 e não há argumentos padrão em Go, então o programador deve pedir explicitamente para derivar a base do prefixo da string especificando 0 para a base.

Não posso dizer que alguma vez precisei usar _ em uma string sendo analisada. Na verdade, menos óbvio.

@nathany , sugiro um problema separado. Eu concordo que se decidirmos permitir 0b , pode fazer sentido também permitir 0o para consistência (e então podemos querer que o gofmt reescreva automaticamente 0 -prefix octais em 0o prefixo octais para que o anterior possa ser lentamente retirado da base de código). Mas esta proposta é sobre literais inteiros binários; vamos continuar assim.

Minha pergunta original não recebeu uma resposta, então li todo o tópico novamente para ver por que um tópico
com tantos polegares para cima, tem tão pouca discussão.

Até agora, a proposta pede literais binários pelos seguintes motivos:

outras línguas os têm

A proposta apresenta detalhes meticulosos sobre como outras línguas os possuem e como os outros estão acostumados com eles. Isso já foi um motivo bom o suficiente antes?

eles são "mais legíveis"

Discordo. Eles são um padrão covarde de uns e zeros que não têm pronúncia fácil sem um
conversão para base16.

  • Você só sabe

0b11101010 vs 0xea. Você nem mesmo precisa pensar no que está sendo direcionado, você apenas
saiba disso assim que der uma olhada.

_O primeiro bit de ordem inferior, e o terceiro bit de ordem inferior e o quinto bit de ordem inferior estão desligados, mas não o resto deles. E há [conta a quantidade total de bits duas vezes para se certificar de que o número está certo] oito
bits total._

Eu sei qual é o padrão e provavelmente irei me lembrar dele por alguns segundos. Como é esse conhecimento
inerentemente útil?

  • Go vs C ++

Alguns argumentos representam mal seus benefícios, talvez de forma não intencional. Em um exemplo particular em
neste tópico, o seguinte trecho foi postado comparando go e 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

O problema é que o C ++ é meticulosamente alinhado enquanto o Go não está formatado, não tem um bloco const e usa incorretamente decimal em vez de hex (que você não pode converter facilmente em binário dividindo cada dígito hexadecimal em quatro binários) .

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

especificações de protocolos publicam binários às vezes

Outro exemplo que acabou de me queimar foi definir endereços nos protocolos incorporados
(I2C, SPI,> CAN, etc ...) onde muitas vezes há um endereço definido como uma constante binária no
folha de dados deslocada> que tem algum tipo de bit de leitura / gravação como parte do valor. Convertendo
transformá-los em hexadecimal adiciona mais uma camada de tradução que o cérebro humano tem que fazer, portanto, mais uma
coisa a ser questionada durante a depuração.

O problema é que o cérebro humano não deveria estar fazendo isso por você em primeiro lugar. |

Considere sua experiência de depuração novamente. Vão despejar literais inteiros binários para stderr ou
e grep para eles mais tarde? Você compartilhará esses números com os colegas, dizendo cada 1
e 0 em voz alta? Provavelmente, você prefere enviar e transmiti-los em hexadecimal, e se isso for verdade, é
também é verdade que o código-fonte deve expressar esses dígitos em hexadecimal, a fim de eliminar a necessidade
para o cérebro humano (ou programa) fazer ainda mais trabalho para o leitor.

Muitas especificações expressam 1010 para significar um fluxo de bits que consiste nesses estados solicitados. Isso não mapeia para a noção de byte-wise de literais inteiros binários, e certamente vai queimar alguém esperando
para implementar um leitor de fluxo de bits. (Eu preferiria implementar um leitor de fluxo de bits na biblioteca padrão do que oferecer suporte a literais inteiros binários).

Acabei de encontrar essa falta de recurso hoje. No meu caso de uso de exemplo, estou usando o dia da semana inteiro
campo de uma data (0..6 significa domingo .. sábado) e comparando-o com uma máscara de bits de preferência.
Como a fonte do inteiro é programática, não defino um conjunto de constantes para cada dia
da semana (meu código não tem nenhuma razão para falar sobre SUNDAY especificamente), então 1 << 3 sintaxe
não é útil aqui. No entanto, quero um valor padrão para a máscara de bits de preferência, que seria
talvez 0b0111110. Obviamente, é fácil escrever esse padrão como decimal (126) ou hex (0x7e), mas
é consideravelmente mais claro escrevê-lo em binário.

Eu teria os dias da semana como constantes não exportadas e construiria a máscara OR ing seus valores. Eu discordo que literais inteiros binários ajudariam a deixar qualquer coisa mais clara nessa situação.

@as Obrigado pelo seu comentário. Foi gravado.

É claro que não _precisamos_ literais inteiros binários; temos uma maneira razoavelmente próxima de expressar esses números usando literais hexadecimais (e eu indiquei isso em minha postagem no

Talvez a melhor maneira de pensar sobre essa questão é se queremos trazer Go para igualar a maioria das outras linguagens de programação a esse respeito e completar o conjunto de representações literais inteiras apoiando todas as bases relevantes (2, 8, 10, 16).

Essa é uma pergunta separada do sentimento pessoal sobre a utilidade dos literais binários e pode ser mais fácil de responder.

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

Veja https://golang.org/cl/152338 para as mudanças de especificações pertinentes a esta proposta (ignorando separadores _ nesta primeira etapa).

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

Eu estava procurando benchmark para vários algoritmos de classificação onde pseudo-aleatório foi definido como 0xff & (i ^ 0xab) Se fosse 0b10101011 vez de 0xab , seria mais legível. Estou surpreso que não haja literais binários em Go, nem mesmo uma proposta ...

@andrewmed Esta

Entendi obrigado

Publicamos uma proposta combinada para # 19308, # 12711, # 28493 e # 29008 em golang.org/design/19308-number-literals .

Observe que esta será a primeira proposta a seguir o processo descrito na postagem do blog: teremos tudo pronto para começar e verificado no início do ciclo do Go 1.13 (1º de fevereiro), passaremos os próximos três meses usando esses recursos e solicitação de feedback com base no uso real e, em seguida, no início do congelamento do lançamento (1º de maio), tomaremos a "decisão de lançamento" sobre incluir o trabalho no Go 1.13 ou não.

Obrigado por seus comentários e toda a sua ajuda para melhorar o Go.

Originalmente sugerido para mim por @rsc : pode ser sábio descontinuar (mas ainda suportar) 0X para hexadecimal e não adicionar 0B (desnecessário) e 0O (desnecessário, confuso e difícil de ler).

@robpike ... e faça o gofmt começar a mudar 0X para 0x.

@josharian , sim, eu também

Mas para 0X -> 0x pode ser feito em gofmt, sim.

Não tenho sentimentos fortes sobre 0B vs 0b e 0O vs 0o (muitos editores de código escrevem um zero com uma barra que parece diferente de um O maiúsculo; pessoalmente, sempre uso minúsculas).

Mas o ponto principal de adicionar esses novos formatos é ser compatível com outras linguagens e aliviar a dor das pessoas que vêm dessas linguagens, e talvez traduzir códigos vindos de outros lugares. Isso anularia esse propósito se a dita pessoa ou código usasse letras maiúsculas nesses prefixos e Go não pudesse digerir esses literais, afinal.

Também noto que haverá um pouco de inconsistência com o expoente onde permitimos E e e (e recentemente P e p).

Em suma, embora eu apoie totalmente o sentimento, desautorizar 0B em maiúsculas parece uma diferença gratuita que não ajuda as pessoas acostumadas com 0b em minúsculas de qualquer maneira (que eu estou supondo que seja a maioria) e prejudica os outros.

Por outro lado, fazer com que gofmt faça a alteração automaticamente (ou talvez com -s) parece uma boa ideia.

como um desenvolvedor embarcado que trabalha muito com bits e máscaras de bits individuais, os literais binários seriam uma mudança bem-vinda. Eu recentemente os descobri em (GC) C e fiquei agradavelmente surpreso.
é claro que praticamente qualquer um pode entender razoavelmente rapidamente 0x1 , 0x80 e 0x8000 . mas algo como 0x1c faz pausar. Claro, (7 << 2) é um pouco melhor 0b00011100 é apenas mais legível e transmite o significado - três bits contíguos 2 posições à esquerda - mais claramente.

Mudança https://golang.org/cl/157677 menciona este problema: cmd/compile: accept new Go2 number literals

Mudança https://golang.org/cl/159997 menciona este problema: go/scanner: accept new Go2 number literals

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

Mudança https://golang.org/cl/160239 menciona este problema: go/constant: accept new Go2 number literals

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

Mudança https://golang.org/cl/160247 menciona este problema: fmt: scan new number syntax

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

Mudança https://golang.org/cl/160248 menciona este problema: text/template: accept new number syntax

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

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

Mudança https://golang.org/cl/160184 menciona este problema: cmd/gofmt: normalize number prefixes and exponents

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

Como um lembrete, apresentamos um novo processo para essas alterações de idioma relacionadas ao Go 2 em nossa postagem do blog blog.golang.org/go2-here-we-come. Vamos aceitar provisoriamente uma proposta, fazer alterações no terreno no início de um ciclo, obter experiência de uso e, em seguida, tomar a decisão final de aceitação três meses depois, no congelamento. Para o Go 1.13, isso significaria fazer uma mudança quando a árvore abrir em fevereiro e tomar a decisão final quando a árvore congelar em maio.

Vamos aceitar provisoriamente esta proposta para o Go 1.13 e planejar sua implementação quando a árvore for aberta. O estado do problema para "aceitação provisória" será marcado como Proposta-Aceita, mas deixado em aberto e marcado para a versão Go (Go1.13 aqui). No congelamento, revisaremos o problema e o encerraremos se ele for finalmente aceito.

Mudança https://golang.org/cl/161098 menciona este problema: spec: document new Go2 number literals

Mudança https://golang.org/cl/161199 menciona este problema: text/scanner: accept new Go2 number literals

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

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

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

Como um lembrete, apresentamos um novo processo para essas alterações de idioma relacionadas ao Go 2 em nossa postagem do blog blog.golang.org/go2-here-we-come. O ciclo de desenvolvimento do Go 1.13 acabou e é hora da decisão final.

O feedback sobre as mudanças na literal numérica do Go 2 foi fortemente positivo, com muito poucas vozes negativas. Essas mudanças modernizam e harmonizam a sintaxe literal numérica de Go sem adicionar complexidade significativa à linguagem: agora há uma notação de prefixo uniforme para as três bases numéricas não decimais comuns, que corresponde à notação usada em outras linguagens de programação modernas. A introdução de literais de ponto flutuante hexadecimal aborda um ponto problemático para as pessoas que se preocupam com o código numérico. O sufixo “i” agora pode ser usado com qualquer número literal (não imaginário) para criar uma constante imaginária de maneira uniforme. E, finalmente, os sublinhados podem ser usados ​​para dividir literais mais longos em grupos de dígitos para facilitar a leitura.

Proposta aceita para Go 1.13. Fechando porque as mudanças aconteceram.

- rsc para revisão da proposta

Mudança https://golang.org/cl/189718 menciona este problema: compiler: support new numeric literal syntax

Esta página foi útil?
0 / 5 - 0 avaliações