Go: 提案:仕様:2進整数リテラル

作成日 2017ĺš´02月27日  Âˇ  91コメント  Âˇ  ソース: golang/go

現在、Goは、期待する標準の10進リテラルに加えて、8進および16進整数リテラルをサポートしています。 このグループを完成させるために、2進整数リテラルも追加することを提案します。 これらは、整数リテラルの新しいプレフィックスとして0bまたは0Bの形式で提供されます。

最初の免責事項

これは、Goのソースコードに初めて飛び込んだものであり、主に、変更を送信するなどして足を濡らすための学習体験でした。 そうは言っても、私はありとあらゆる批判、コメント、提案に感謝します。

「理由」:先行技術

バイナリリテラルは、次のような主流の言語にも存在するか、登場しています。

上記のすべてのケースは、バイナリリテラルのプレフィックスに0bまたは0Bを使用するという慣習に落ち着きました。これは、Goにとってもかなり快適で賢明な選択であり、不必要な発明を回避し、これらの他の前述の言語から来るプログラマーに類似性を提供します。

「理由」:続き

これはすでに機能を実装した後であり、特にバイナリリテラルに関連するよりも、8進構文の変更に関係しているにもかかわらず、これに関連するいくつかの以前の議論を見つけることができました。 しかし、 @ griesemerのhttps://github.com/golang/go/issues/12711#issuecomment -142338246は、「8進数の「o」と2進数表記の「b」の両方がGoの設計でも議論された」と述べています。お金を稼ぐには十分ではありません。」 しかし、私はこれを言語にそれほど単純なものを追加することに反対する良い議論とは考えていません。 特に、最近ますます多くの言語がバイナリリテラルの構文を採用しているという事実を考慮すると、以前のGo設計の決定を新しい観点から検討する必要があるようです。

使用例

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

実装

これは私にとってより多くの学習経験であると述べたように、私はすでにこの機能を実装するための変更を用意しています。

CL-37502仕様:2進整数リテラルの構文を指定します
CL-37503 cmd / compile / internal /
CL-37504 go / scanner:2進整数リテラルをスキャンします
CL-37505 strconv:2進整数リテラルの解析をサポート
CL-37506テスト:バイナリリテラルの使用法でint_litを拡張します

FrozenDueToAge Go2 LanguageChange NeedsDecision Proposal Proposal-Accepted

最も参考になるコメント

前述の言語が前進し、バイナリリテラルのサポートが追加された理由を見てみましょう。 リストの最初のものであるC ++ 14から始めましょう。 当時Googleの従業員だったJamesDennettが提起したポイントは何でしたか?

バイナリリテラルに0b / 0Bプレフィックスを使用することは、既存のGCC拡張機能(Clangでもサポートされています)であり、Java 7、Python、およびDと同じ構文です。

この特定のポイントがGoに利益をもたらすのはなぜですか?

言語に精通していること。

多くの開発者はプログラミング言語からプログラミング言語に移行します。 私が間違っている場合は訂正してください。しかし、私たちは皆、ある言語から別の言語で知っていることを試します。 ある意味で、GoがCとC ++に精通していることは、GCのような特定の機能を望んでいるが、他の言語は好きではないような種類の開発者を惹きつけたと言えます。 これが、私が現在インターンをしている会社がGoへの移行を選択した理由の1つです。

経験豊富な開発者に加えて、初心者の開発者にとってなじみのある利点が何であるかを見てみましょう。 @eddieringleが言及したフラグのユースケースも取り上げましょう。 フラグがどのように機能するかを完全な初心者に説明することは、8進数または16進数で説明する必要がある場合、人がフラグを学習する必要があるため、非常に困難です。

最後に、すべての言語の目的(少なくともそれが私が望んでいることです)がクリーンなコードを書くことであることをここに追加したいと思います。 そして、それは私たち全員が関係なく同意するものだと思います。 他の人のコードを調べると、バイナリリテラル定数のリストがある場合、それらがフラグであることが説明なしですぐに明らかになります。 16進数または8進数を使用する場合、同じことはそれほど単純ではありません。 以下は比較です。

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

最後の定数がフラグに使用されているという事実を考慮する必要はないと思います。 これらも非常に少数のフラグであるため、フラグが増えると、これは間違いなく加算されることに注意してください。 最初の定数0x1Eは、コンテキストなしで宣言されたときに間違いなく頭を回転させる可能性があります。 バイナリリテラルを単独で使用すると、変数がフラグとして使用される可能性があることを示している可能性があります。

参照されているC ++ PDFは、サポートのために前述の言語をさらに参照しています。 それでは、次にそれらを見てみましょう。 JDKのバイナリリテラルに関する2009年のDerekFosterによる(元の?)提案を見つけました。 ソース

私が完全に同意する最初の質問は、JDKに8進表現があるのに、JDKには2進表現がない理由です。 過去数年間、私は自分自身に考えたことはありませんでした。「ああ、8進数は私のコードをよりきれいにするでしょう!」 ただし、これは私が以前に述べたポイントである親しみやすさを指します。 しかし、それが私の以前に述べた点に追加することが1つあります。

ただし、処理されるデータが基本的にビット指向である場合、ビットの範囲を表すために16進数を使用すると、プログラマーにとって追加の変換が必要になり、これがエラーの原因になることがよくあります。 [...]次に、その仕様にコーディングするプログラマーは、そのような各値を2進表現から16進に変換する必要があります。 [...]ほとんどの場合、プログラマーは頭の中でこれらの翻訳を行い、うまくいけば正しく翻訳します。 ただし、エラーは簡単に忍び寄る可能性があり、結果の再検証は頻繁に行うほど簡単ではありません。

バイナリではなくハードウェアで主に使用される16進表記と8進表記は、人的エラーを引き起こす可能性があります。 以前に行った比較では、8進数だと思ったものをGoogleに入力して、自分の頭で何をしたかを確認し、答えを確認しました。 2進数で書くときは自動的に自分のケースを確信しますが、16進数や8進数で書くときは確信が持てません。 そして、これを1日に何度行っても、頭の中でバイナリ形式を考える必要があり、そうしている間にエラーが発生する可能性があるため、コードを書くのが難しくなります。

なぜ8進表記があるのに、2進表記がないのかという質問をさらに深く掘り下げるために、JDKの2進文字通りの提案の著者であるDerekFosterからも尋ねられた別の質問があります。 8進表記の0プレフィックス?」 @griesemerは、新しい機能を実装するときに銃を飛び越えてはいけないとコメントしました。

銃をジャンプする前に、他の人の言うことを待って見てみましょう。 ありがとう。

しかし、8進表記を実装するとき、Goは銃を飛び越えていませんか? その引数が「他の言語がそれを行うため」だった場合、なぜその引数をバイナリリテラルに使用できないのでしょうか。 そうでない場合、8進表記の0プレフィックスが、人々を混乱させるときに言語に組み込まれた理由は何でしたか?

「0b1」は16進数の「0xB1」と同じ値を表していると誤解される人がいるかもしれません。 ただし、この問題は8進数/ 10進数で長年存在しており(「050」と「50」の混同)、大きな問題ではないように思われることに注意してください。

-デレク・フォスター

バイナリリテラルは私たち全員が頭の中で言及しているものであるため、バイナリリテラルを支持する点はこれ以上ないようです。 そのため、他の言語への提案はこのように簡潔でした。 ただし、それほど迅速にシャットダウンする理由にはなりません。

全てのコメント91件

これは以前に出てきました。 これを展開するにはかなりの量の作業が必要であり、コンパイラと仕様の変更は簡単です。 しかし、一貫性を持たせる必要のあるライブラリもたくさんあります(strconv、math / bigなど)。

この方向に変更を加える場合、それはより徹底的であり、任意のベースをサポートする必要があります。 私はこれにそのまま反対します。

@griesemerはい、送信しようとしている変更によってstrconvも変更されます(私の理解では、実際にはこの変更をサポートする必要があります)。

@griesemerただし、変更が任意のベースをサポートする必要があるか、そうでない場合は変更がまったく行われないことに同意しません。 以前の読書から、それはGo2の良い目標になるように思えます。 これは、他の言語の開発者がGoを使用するときに期待する可能性のある構文でGo1を磨くだけです。 (つまり、Base-2は十分に一般的なケースであり、おそらく8進数よりも一般的です。base-14またはwhat-have-youはそれほど一般的ではありません。)

CL https://golang.org/cl/37503は、この問題について言及しています。

CL https://golang.org/cl/37504は、この問題について言及しています。

CLhttps : //golang.org/cl/37502にこの問題が記載されています。

CL https://golang.org/cl/37505は、この問題について言及しています。

CLhttps : //golang.org/cl/37506はこの問題について言及しています。

しかし、私はこれを言語にそれほど単純なものを追加することに反対する良い議論とは考えていません。

それらを追加することを支持することも、特に強力な議論ではありません。

私見では、バイナリリテラルをサポートすることでgoコードを書く人々にどのような利点がもたらされるかを正確に説明する「理由」セクションを拡張する必要があります。

私はそれらが特に有用だとは思いません。 hexは、「ビットレベルの意味」を持つリテラルのはるかに読みやすくコンパクトな形式です。

あなたは「使用例」を挙げましたが、それはあまり説得力がありません。 0xfを使用してこれらの定数を記述し、他の定数をシフトします。

@EddieRingleこの提案は広く議論されておらず、受け入れられていません。 コードレビューで私たちをスパムしないでください。 Goチームは、実際に重要な作業を十分に行うことができます。

言語に単純な機能を追加するのは簡単であることは誰にとっても明らかです。 多くの人がこの機能を望んでいることも明らかです(私自身もいつかそれが好きだったでしょう)。 しかし、それは、できるという理由だけで、すべきであるという議論ではありません。 しかし、言語への小さくて単純な追加には、長期的なコストがかかります。 これを受け入れると、将来、より一般的なメカニズムを持つことがさらに難しくなり、下位互換性を維持する必要があります。

銃をジャンプする前に、他の人の言うことを待って見てみましょう。 ありがとう。

no-me-tooポリシーのリマインダー: https :

建設的なコンテンツのない意見は、Githubの絵文字反応を使用して表現できます。

@ALTree

私見では、バイナリリテラルをサポートすることでgoコードを書く人々にどのような利点がもたらされるかを正確に説明する「理由」セクションを拡張する必要があります。

私はそれらが特に有用だとは思いません。 hexは、「ビットレベルの意味」であるIMOを持つリテラルの場合、はるかに読みやすくコンパクトな形式です。

実際、私は反対のことを主張したいと思います。 多くの場合、16進数はよりコンパクトですが、バイナリリテラルは正確な「ビットレベル」表現であるため、可能な限り読みやすくなります。

@griesemer

この提案は広く議論されておらず、受け入れられていません。 コードレビューで私たちをスパムしないでください。 Goチームは、実際に重要な作業を十分に行うことができます。

謝罪。 元々は単一の変更でしたが、Goポリシーは影響を受けるコードベースの領域に基づいてコミットを分割することであるように思われるため、最終的にそれらを分割しました。 ボットが変更のたびにここで個別のコメントをすることを私は知りませんでした。 私はそれをあなたにスパムと呼ぶほど冷たくはありませんが、私の自由な時間を使って私が費やした努力が重要でないことを意味するものでもありません。

しかし、言語への小さくて単純な追加には、長期的なコストがかかります。 これを受け入れると、将来、より一般的なメカニズムを持つことがさらに難しくなり、下位互換性を維持する必要があります。

前に述べたように、汎用ルート(私も好む)は、既存の(紛らわしい)8進構文の非推奨/削除も促進しますね。 私が得た感覚は、汎用構文(たとえば、基数2の場合は2r0010または2x0010 )は、Go2向けの発明であり、とにかく重大な変更を歓迎するというものでした。

潜在的なGo2はさておき、「_これを受け入れると、将来、より一般的なメカニズムを持つことはさらに困難になるでしょう_」という声明に対処するために:これがどのように真実であるかはわかりません。 バイナリリテラルプレフィックスの追加は、代替の汎用構文、特に#12711で説明した構文と直交します(実際、その構文は16進リテラルと直接競合しますが、この提案されたバイナリリテラル構文とは競合しません)。 これらは、汎用構文が既存の8進数、16進数、および10進数のリテラルと同じように並んで存在します。

謝罪。 元々は単一の変更でしたが、Goポリシーは影響を受けるコードベースの領域に基づいてコミットを分割することであるように思われるため、最終的にそれらを分割しました。 ボットが変更のたびにここで個別のコメントをすることを私は知りませんでした。 私はそれをあなたにスパムと呼ぶほど冷たくはありませんが、私の自由な時間を使って私が費やした努力が重要でないことを意味するものでもありません。

ボットがCLに関するメールを送信するだけでなく、メールで送信された各CLは、Goレビュー担当者が時間をかけてレビューするように要求するものです。

0b構文は使い慣れているので便利ですが、本当の目標が単にバイナリリテラルを言語に追加することである場合は、使い慣れたものよりも一般的なソリューションの方がはるかに望ましいと思います。

2.0より前に汎用オプションを実装できない技術的な理由はありますか? 最近、16進数よりもバイナリリテラルが優先されるケースがいくつかあります。2.0まで(おそらく何年も)待つのではなく、1.9または1.10でそのオプションを使用すると便利です。

@wedowバイナリリテラルが役立つ特定の実際のケースを確認するのに役立つと思います。 バイナリリテラルが役立つ場合を共有してください。 ありがとう。

「任意の拠点をサポートすべき」というのは、価値のある異議ではないと思います。 複雑さ/コストが追加され、追加のメリットはほとんどまたはまったくありません。 私がハッキングしてきたすべての年にわたって、私が使いたいと思っている人々について聞いた有用なベースは、 2、8、10、12 、および16であり、おそらく64です(結局、base64エンコーディングがあります) 。

前述の言語が前進し、バイナリリテラルのサポートが追加された理由を見てみましょう。 リストの最初のものであるC ++ 14から始めましょう。 当時Googleの従業員だったJamesDennettが提起したポイントは何でしたか?

バイナリリテラルに0b / 0Bプレフィックスを使用することは、既存のGCC拡張機能(Clangでもサポートされています)であり、Java 7、Python、およびDと同じ構文です。

この特定のポイントがGoに利益をもたらすのはなぜですか?

言語に精通していること。

多くの開発者はプログラミング言語からプログラミング言語に移行します。 私が間違っている場合は訂正してください。しかし、私たちは皆、ある言語から別の言語で知っていることを試します。 ある意味で、GoがCとC ++に精通していることは、GCのような特定の機能を望んでいるが、他の言語は好きではないような種類の開発者を惹きつけたと言えます。 これが、私が現在インターンをしている会社がGoへの移行を選択した理由の1つです。

経験豊富な開発者に加えて、初心者の開発者にとってなじみのある利点が何であるかを見てみましょう。 @eddieringleが言及したフラグのユースケースも取り上げましょう。 フラグがどのように機能するかを完全な初心者に説明することは、8進数または16進数で説明する必要がある場合、人がフラグを学習する必要があるため、非常に困難です。

最後に、すべての言語の目的(少なくともそれが私が望んでいることです)がクリーンなコードを書くことであることをここに追加したいと思います。 そして、それは私たち全員が関係なく同意するものだと思います。 他の人のコードを調べると、バイナリリテラル定数のリストがある場合、それらがフラグであることが説明なしですぐに明らかになります。 16進数または8進数を使用する場合、同じことはそれほど単純ではありません。 以下は比較です。

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

最後の定数がフラグに使用されているという事実を考慮する必要はないと思います。 これらも非常に少数のフラグであるため、フラグが増えると、これは間違いなく加算されることに注意してください。 最初の定数0x1Eは、コンテキストなしで宣言されたときに間違いなく頭を回転させる可能性があります。 バイナリリテラルを単独で使用すると、変数がフラグとして使用される可能性があることを示している可能性があります。

参照されているC ++ PDFは、サポートのために前述の言語をさらに参照しています。 それでは、次にそれらを見てみましょう。 JDKのバイナリリテラルに関する2009年のDerekFosterによる(元の?)提案を見つけました。 ソース

私が完全に同意する最初の質問は、JDKに8進表現があるのに、JDKには2進表現がない理由です。 過去数年間、私は自分自身に考えたことはありませんでした。「ああ、8進数は私のコードをよりきれいにするでしょう!」 ただし、これは私が以前に述べたポイントである親しみやすさを指します。 しかし、それが私の以前に述べた点に追加することが1つあります。

ただし、処理されるデータが基本的にビット指向である場合、ビットの範囲を表すために16進数を使用すると、プログラマーにとって追加の変換が必要になり、これがエラーの原因になることがよくあります。 [...]次に、その仕様にコーディングするプログラマーは、そのような各値を2進表現から16進に変換する必要があります。 [...]ほとんどの場合、プログラマーは頭の中でこれらの翻訳を行い、うまくいけば正しく翻訳します。 ただし、エラーは簡単に忍び寄る可能性があり、結果の再検証は頻繁に行うほど簡単ではありません。

バイナリではなくハードウェアで主に使用される16進表記と8進表記は、人的エラーを引き起こす可能性があります。 以前に行った比較では、8進数だと思ったものをGoogleに入力して、自分の頭で何をしたかを確認し、答えを確認しました。 2進数で書くときは自動的に自分のケースを確信しますが、16進数や8進数で書くときは確信が持てません。 そして、これを1日に何度行っても、頭の中でバイナリ形式を考える必要があり、そうしている間にエラーが発生する可能性があるため、コードを書くのが難しくなります。

なぜ8進表記があるのに、2進表記がないのかという質問をさらに深く掘り下げるために、JDKの2進文字通りの提案の著者であるDerekFosterからも尋ねられた別の質問があります。 8進表記の0プレフィックス?」 @griesemerは、新しい機能を実装するときに銃を飛び越えてはいけないとコメントしました。

銃をジャンプする前に、他の人の言うことを待って見てみましょう。 ありがとう。

しかし、8進表記を実装するとき、Goは銃を飛び越えていませんか? その引数が「他の言語がそれを行うため」だった場合、なぜその引数をバイナリリテラルに使用できないのでしょうか。 そうでない場合、8進表記の0プレフィックスが、人々を混乱させるときに言語に組み込まれた理由は何でしたか?

「0b1」は16進数の「0xB1」と同じ値を表していると誤解される人がいるかもしれません。 ただし、この問題は8進数/ 10進数で長年存在しており(「050」と「50」の混同)、大きな問題ではないように思われることに注意してください。

-デレク・フォスター

バイナリリテラルは私たち全員が頭の中で言及しているものであるため、バイナリリテラルを支持する点はこれ以上ないようです。 そのため、他の言語への提案はこのように簡潔でした。 ただし、それほど迅速にシャットダウンする理由にはなりません。

これは別のオプションです。これは、どの整数定数よりも明確に思えます。

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

(そして、マスクは0x1eではなく0xfであるべきではありませんか?)

少なくともGo1では、バイナリ定数を追加することには少し反対ですが、Go2ではそれらを追加することになります。 違いの理由は、何らかの理由で誰かがGo 1.8で立ち往生している場合、Go 1.9がバイナリ定数で出てくるとき、その人のコードの(推移的な)インポートの1つがバイナリ定数を使用していると、彼らはもはやGo1.8を使用したプロジェクト。 彼らはベンダーまたはアップグレードする必要があります。 前方互換性のない機能を追加するには明確なコストがかかり、その有用性と比較検討する必要があります。

{2,8,10,16}にない基地は必要ないと私は同意します。 8進数の場合は特に不安定なようです。Go2で8進数を削除するためです。

@ randall77シフトがきれいに見えることに同意し

(そして、マスクは0x1eではなく0xfであるべきではありませんか?)

MASKという名前は、単にJDKの提案から取られたものであり、他の定数と実際には一致していません。 しかし、 0x1Eと16進数がすでに混乱を引き起こしていることを示しています。

Go 2に移行したいというあなたの主張は理解できますが、Goバージョンを1.9から1.8にダウングレードするプロジェクトをサポートする必要があることに同意しません。 それは、言語の変更を対処するのに悪夢にするでしょう。 ただし、Goがこれをどのように見ているかはわかりません。Goがどのような互換性を念頭に置いているかに従うのが、最も賢明です。

Go2で8進数を削除するというあなたの立場を心から支持します。

以前のコメントを読み直しました(具体的には、「Goチームは実際に重要な作業を十分に行うことができます」)。 私が実際に言おうとしていたことのかなり不快な定式化であったこの声明をお詫びしたいと思います。 それでは、もう一度試してみましょう。もう少し詳しく説明し、今回は適切なトーンを見つけてください。

十分に実証されており、必要に応じてプロトタイプの実装が付属している提案に感謝します。 とはいえ、Goの提案プロセスは意図的に軽量であり、提案を理解するために要求または必要でない限り、提案者が追加の作業を行う必要はありません。 要求されていない、および/または問題を修正しない変更リストを送信することは、誰かが時間をかけてそれらを見る必要があるため(延期または閉じるためだけの場合)、逆効果です。 事前にコードのプロトタイプを作成/作成したい場合は、他の場所で変更にリンクすることをお勧めします(たとえば、プライベートGitHubコミット)。 これにより、Goチームと外部の貢献者に選択肢が残ります。必要に応じてそのコードを確認するか、優先度の高いアイテムに焦点を合わせるかを決定できます。 ありがとう。

@griesemer Gotcha、わかりました。それは理にかなっています。 GoチームはAOSPと同じようにGerritを扱っていると思い、これについて話し合っている間、私の変更がそこに存在する可能性があると考えました。 ここGitHubでブランチにリンクするのはとにかく手間がかからないので、双方にメリットがあると思います。 :)

私の主な目標はコンパイラをハックすることだったので、私は実際に最初に作業を行いました。 提案として提出することにしたのは事後だった。

@AndreasBackx Goの8進数の先行0については、第151号で説明されています。 #12711も参照してください。

1セットビット定数を定義する場合、シフトは0b00001000..00よりも読みやすくなります。これは、シフトバージョンでは、どのビットが設定されているかを理解するためだけに画面上のゼロの束を数える必要がないためです。 ; シフト値を読み取るだけです。

0b100000000000000000000000 vs 1 << 23

実際の使用法に関する限り、一般的な可変長整数エンコード方式は、「続きを読む」ために上位ビットを使用することです。 gitpackfilesを抽出するためにそれを使用しなければなりませんでした。 さまざまなベースの下位ビットを抽出するコードは次のとおりです。

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

個人的には、バイナリバージョンの方が意図がはっきりしていると思います。

前述のシフトオプションはまだあります
読めないと思う場合は、ヘルパー関数を使用してください

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

@AndreasBackx 、 1<<12は、これらすべてのゼロを数える必要がないため、 0b0001000000000000よりも明確です。 12が11と13にあるか、 iota使用しているため、これがマスクであることは明らかです。 任意のパターンに一致する必要がある場合、たとえば、命令ワードからビットをマスキングする場合、ビットの処理に慣れているプログラマーは0xaeを読み取り、0xa、ten、1010、ニーモニックten-を知っているため、10101110を「参照」できるため、16進数の方が適しています。 10、九九を学ぶのと同じように、65はASCII Aなどです。16進数は、人間の読者にとって解析しやすい、より密度の高い表現です。

@ randall77、0644、02775など、8進数なしでは少し面倒ではありませんか? それがまだ動き回っている理由です。

@RalphCorderoy :はい、 os.FileModeを作成するという唯一の理由で、8進数が存続しているように見えます。
0664 = 6<<6 + 6<<3 + 4 、これはそれほど面倒ではありません。 osがシンボリック定数を提供して、これを簡単にするか、少なくとも明確にするとよいでしょう。

ゼロのカウントの問題を回避する方法はすでにわかっています。 0b1e10をサポートして、バイナリで1の後に10個のゼロを意味するようにする必要があります。 確かに、バイナリ定数を追加するのではなく連結する方法があれば、これはうまくいくでしょう。

私の主な目標はコンパイラをハックすることだったので、私は実際に最初に作業を行いました。

優秀な。 これについて話し合っている間、コンパイラをハックし続ける場所についてのアイデアが必要な場合は、遠慮なく私にメールを送ってください-(github username)@gmail。

@RalphCorderoy 1 << 12は、これらすべてのゼロをカウントする必要がないため、0b0001000000000000よりも明確です。

この問題の解決策は、ある種の分離を可能にすることです。 Javaでは、数値リテラルでアンダースコアを使用できます。 #42で簡単に議論されましたが、そもそもその問題についてコメントがあったとしても、それに対する議論はあまりありませんでした。

@ianlancetaylorのソリューションも検討する必要があります。

12は11から13の間にあるか、iotaを使用しているので、それがマスクであることは明らかです。

申し訳ありませんが、これはおそらくあなたの場合です。 しかし、他のすべての人のためではありません。

任意のパターンに一致する必要がある場合、たとえば、命令ワードからビットをマスキングする場合、ビットの処理に慣れているプログラマーは0xaeを読み取り、0xa、ten、1010、ニーモニックten-を知っているため、10101110を「参照」できるため、16進数の方が適しています。 10、九九を学ぶのと同じように、65はASCIIAなどです。

これは、私が以前に述べたようにコードにエラーの余地を残し、それが正当な理由であると判断した他の言語に対して提案されました。 また、ここでは、すべての「プログラマー」が頭のてっぺんから離れたヘクスを知っていると想定していますが、そうではありません。 多くのハードウェアで作業するかもしれませんが、ほとんどの人はそうではありません。 間違いなく初心者は、16進表現よりも2進リテラルを好むでしょう。

16進数は、人間の読者が解析しやすい、より密度の高い表現です。

密度が高いということは、それがよりきれいであることを意味しますか? いいえ、そうではありません。 人々はいつもクレイジーなことのためにワンライナーを書いています、そしてそれらがいくぶん印象的である理由はそのコードがとても密で読めないので、私たちは皆、各キャラクターの意味の後ろにどんな魔術が隠されているのか疑問に思います。

1 << 10は0b1e10よりもはるかに明確です。

バイナリリテラルは読みにくいと思います。 多くの場合、必要なものは3ビットまたは4ビットのセグメントに切り上げられます。これは、8進数または16進数での読み取りと書き込みがはるかに簡単で、エラーが発生しにくいものです。 物事がそのような均等な境界に丸められない場合、シフトは読み取りと書き込みがはるかに簡単になり、エラーが発生しにくくなります。

何らかの形式の連結により、不整合が犠牲になりますが、バイナリリテラルの読み取りと書き込みが容易になります。 バイナリリテラルを連結できるのに、他のタイプの数値リテラルを連結できないのはなぜですか? なぜ16進数ではないのですか? この時点で、この議論は無限になります。

個人的には、ある種の一般的な基数メカニズムを好みます。 私はバイナリリテラルがテーブルに十分なものをもたらすとは思いません(そして私は低レベルのコードを書くだけです)。

また、私たちは以前にこの議論を数回行ったことがあると確信しています。

(補足として、8進数の終焉は大幅に誇張されています。8進数はファイルモードの設定を超えて役立ちます。私は確かに、2進数のリテラルよりも8進数のリテラルを使用します。)

言語の変更についての議論として多くの個人的な意見が出されているのを見るのは少し驚きです。 個人的にどれだけ役立つかに関するコメントを定量化する方法がわかりません。

何らかの理由で個人的な感情にメリットがある場合は、Javaでバイナリリテラルを使用していると恣意的に言います。100年間プログラミングを行っており、車を所有していると言うことで、これについての意見を検証できます。

次に、シフトを使用してマスクを定義する方が簡単かどうかを議論することは、グレゴリオ暦が中国のカレンダーよりも使いやすいと主張するようなものです。 使いやすいと思ったからといって、誰もがそうするわけではありません。 バイナリリテラルが他の言語に存在するという事実は、シフト引数が単なる代替であるため、シフト引数はあまり引数ではないことをさらに促進するために、誰かがそれらを有用だと思ったことを示しているはずです。

これは以前に出てきました。 これを展開するにはかなりの量の作業が必要であり、コンパイラと仕様の変更は簡単です。 しかし、一貫性を持たせる必要のあるライブラリもたくさんあります(strconv、math / bigなど)。

これはこの提案に対する確固たる議論であり、かなりの量の作業を生み出す変更を行うことに躊躇していることを完全に理解しています。

実際、私は反対のことを主張したいと思います。 多くの場合、16進数はよりコンパクトですが、バイナリリテラルは正確な「ビットレベル」表現であるため、可能な限り読みやすくなります。

バイナリを学ぶことの面白いところは、実際にバイナリを読み書きしてから、それに対して数学を実行する必要があるということです。 16進数、10進数、8進数、base64(lul)で書くと、間接的に2進数を学習するのに役立ちますが、直接学習したいことを学習するだけでも役立つと聞きました(おそらく単なる意見です)。

個人的には、ある種の一般的な基数メカニズムを好みます。

私はすべての言語が文字通りの形でこれを持っていたらいいのにと思います。

@ randall77 :#151で述べたように、8進数を維持する理由はいくつかあります。 はい、1つはファイルモードの設定ですが、それが最後に重要です。 他の2つは、0で始まる整数リテラルへのセマンティクスの変更と、8進定数がこの構文を持つ他のすべてのCのような言語からコードを安全に移植することの重要性です。 確かに、これらのどれも魅力的ではありませんが、一緒になってバーに会います。 とにかく、少なくともGo 1については、問題は決定されています。

バイナリ定数に関しては、私はそれらがそれらの重みを持っているとは思わない。 それらから恩恵を受けるプログラムはほとんどなく、それでも恩恵はわずかです。

@robpike 8進定数のように見えるもの( 0始まり、「0」ではない)のコンパイルに失敗しても安全です。

これはGo2に残しましょう。

なぜ待つのですか? それは何も壊しません。
月には、2017ĺš´3月6日は午後03時19分ラスコックスで[email protected]書きました:

これはGo2に残しましょう。

—
あなたがコメントしたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/golang/go/issues/19308#issuecomment-284535766 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/ABLfW7bN2NicSthvEvMeGEhqExg2et-qks5rjHhtgaJpZM4MNgUY
。

@ DocMerlin 、Goは機能を追加し続ける言語ではないためです。 すべての言語の変更は、グループとして一緒に評価できるようになるまで、基本的に今のところ保留されているため、見た目も感じも、まとまりのある全体のように連携します。 これがGo2とラベル付けされている理由です。

@DocMerlin @bradfitzのコメントに、差し迫ったニーズがあるときに過去に例外を作成したことを追加したいと

これらも非常に少数のフラグであるため、フラグが増えると、これは間違いなく加算されることに注意してください。
SOME_FLAG_D = 0b0000000001000000000000000000000

一目でこれは2 ^ 19または2 ^ 20ですか? 問題がわかりますか?

@davecheneyに感謝し

バイナリリテラルがないために整数のビット操作を処理するルーチンを正しく表現できないユースケースがないことは明らかであり、整数データをあるベースで別のベースに表現してもパフォーマンス面で何も得られません。

ただし、データがベース2で表現されている場合、ビットマスク、バイナリ定数、およびその他のビットマップデータをソースコードで読みやすくすることができるバイナリエンコーディングの状況(ビデオコーデック、データ圧縮、バイナリネットワークプロトコルなど)はたくさんあります。

ビットマップデータを扱う人にとっては、読みやすさとスタイルの問題です。

読みやすさとスタイルは、8進整数リテラル表記が初日にGoでサポートされたのと同じ理由です。 8進整数リテラルのサポートを含めることは、Unixファイルのパーミッションの処理に関係する決定である可能性が最も高いです。 この時代には、Unixスタイルのパーミッションのレガシーサポートとコード内のこのデータの可読性以外に、8進表記の多くの実用的な使用法を想像するのは難しいです。

それでも、8進数のサポートは、8進数の文字列の処理を担当するstrconvに2つの単純な関数しかないことを示すのに役立ちます。

archive / tar / strconv.go:func(p * parser)parseOctal(b [] byte)int64
archive / tar / strconv.go:func(f * formatter)formatOctal(b [] byte、x int64)

バイナリリテラルのサポートを追加した場合の変更の影響を非常に大まかに評価するために考えられる方法の1つは、8進数の同等のサポートのコードフットプリントを確認することです。サポートされています。

現在の私のローカルコピーでは、大まかな検索により、これらのほとんどが解析およびフォーマット操作であることが示されています。

vxv @ vxs :/ gosource $ grep -i-rオクタル* | wc -l
73
vxv @ vxs :/ gosource $ grep -i-rオクタル* | grep "func" | wc -l
2

これは些細で単純な検索であることは確かですが、問題の割合は克服できないタスクを提示しているようには見えません。

心配ない。 記録のために、私はこのレースに犬を飼っていません、私は問題を庭にするためにここにいます。 go2のこの提案の運命を決めるのは他の人次第です

ただし、データがベース2で表現されている場合、ビットマスク、バイナリ定数、およびその他のビットマップデータをソースコードで読みやすくすることができるバイナリエンコーディングの状況(ビデオコーデック、データ圧縮、バイナリネットワークプロトコルなど)はたくさんあります。

私は上記のすべてを使用しましたが、ベース2がこれらに何らかの利点をもたらすとは想像もしていませんでした。 そうでなければ私を説得するための具体的な例を指摘していただけませんか?

読みやすさは、バイナリリテラルを実装する主な理由です。 私は現在、ビットポジショニングを利用するエンジンを作成しています。いくつかのユースケースでuint16、uint32を使用しており、これらのuintの各スライス/セクションは異なる情報を表しています。

チェスでは、uint16の位置にフラグを追加することにより、エンコードされた移動を使用します。 どのセクションがどの情報に関連しているかをコードだけで表示できるように、バイナリリテラルの実装を確認すると便利です。

...
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};

これはC ++ 17からの私のコード例です。 ただし、Goでは次のようになります。

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

ビットとマスクを扱う人のために、クリーンでシンプルなコードを書くのに本質的に役立ちます。

このためのプリコンパイラを入手できなければ、何も書き直す必要はありませんか? 結局のところ、それは(私の目には)astethicsだからです。

(c ++)で設定されているビット

constexpr uint_fast16_t FLAG_SPECIAL0  {0b0001000000000000};

vs

(Go)でどのビットが設定されているか

const FlagSpecial0 = 0x10000

後者の場合にのみすぐにわかるのは私だけではないでしょう。

0b00 ..アプローチを使用すると、16進数を知らなくてもそれを確認できます。 uint16のリストが多いと、読みやすくなります。 サイズがリストされているので、セットビットが13の位置にあることを理解することは、あなたが与えた例では、16進数を使用するよりも簡単です。 1<<13 、16進数よりもはるかに優れているだけでなく、値を検索する必要もありません。値を確認するだけで、どのビットがターゲットになっているかを知ることができます。 ただし、範囲または複数のセットビットの場合は、バイナリリテラルを使用する方が簡単な場合があります。

61440ような後のケースを見ると、すぐにわかると思います。バイナリリテラルよりも、小数を使用して設定されているビットを知る方が簡単だと思いますが、誰もがこれを見るわけではありません。

しかし、10進数で0xfe0または4064である0b0000111111000000ような他のケースを無視しただけです。 私の意見では、バイナリリテラルを使用するとよりクリーンになります。 16ビットの方が大きいですが、バイトを見てください。

0b11101010 vs 0xea 。 何がターゲットになっているのかを考える必要はありません。見ればすぐにわかります。

@andersfylling 、ビットマスクをプログラミングしている場合は、実際に16進数を読み取ることができる必要があります。RangeFlagは61440ではなく0xf000であるため、16ビットのトップニブルであることがすぐにわかります。

この問題について斬新な洞察を持っていると思う人のために、私たちの残りの部分を眠りから覚ます前に、ブラッドがNoMeTooポリシーに言及していることに特に注意して、上からすべてのコメントを読んでください。

16進法とビットシフトはすべて私のために(そして8進ファイルのパーミッションも)行いますが、Cでのビット操作の学習は2進整数リテラルの方が簡単だったのではないかと思います。 上記の例がバイナリでどのように見えるかが好きです。 たぶん私はこれを小さなマスクや小さなマスクのシフトに使うでしょう。

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

(編集:より良いGoの方法はx := y & 0b101<<8 )

今日、この機能の欠如に遭遇しました。 私の例のユースケースでは、日付の整数の曜日フィールド(0..6は日曜日..土曜日を意味します)を使用して、設定ビットマスクと照合しています。 整数のソースはプログラムであるため、曜日ごとに定数のセットを定義しません(私のコードでは、SUNDAYについて具体的に説明する理由はありません)。したがって、ここでは1 << 3構文は役に立ちません。 ただし、設定ビットマスクのデフォルト値が必要です。これはおそらく0b0111110です。 明らかに、このデフォルトを10進数(126)または16進数(0x7e)として記述するのは簡単ですが、2進数で記述する方がかなり明確です。

Re:8進数。python2とpyhon3の間で、0110形式のサポートが終了し、代わりに0o110が必要になることに注意してください。 次に、古い形式をそこにドロップせずに0o110解析をpython2にバックポートし、古いバージョンとの互換性を損なうことなく、エラーが発生しにくい新しい構文の使用を簡単に開始できるようにしました。 python2では、かなりの数のpythonユーザーが、0が埋め込まれた10進数を貼り付けるときに、誤って8進数を宣言してしまい、混乱を招きました。 (一般的な問題:部品データベースの長さが埋め込まれたシリアル番号、または長さが埋め込まれた請求書番号。)これが原因で、実際に30分も混乱して、「明らかに正しい」単体テストが失敗した理由を突き止めようとしました。

一方、私は一度も任意の基数の言語定数のサポートを必要としたことはありません。 誰かが持っているかもしれませんが、それは赤いニシンのようです(そしてそれをサポートするために必要な構文はかなり醜いように聞こえます)。

私を燃やした別の例は、組み込みプロトコル(I2C、SPI、CANなど)でアドレスを定義することでした。ここでは、シフトされたデータシートに、ある種の読み取り/書き込みビットを持つバイナリ定数として定義されたアドレスがよくあります。値の一部として。 それらを16進数に変換すると、人間の脳が実行する必要のある変換のレイヤーがもう1つ追加されます。したがって、デバッグ時にもう1つ疑問があります。

こんにちは@tapir 、私の以前のコメントhttps://github.com/golang/go/issues/19308#issuecomment -352290337、特にhttps://github.com/golang/go/wiki/NoPlusOneを読んでください。NoMeTooが呼び出されるようになりました。

これは、ほぼ同じ(またはそれ以下の)コストで任意の基数表記を許可する反対提案です:#28256。 私は、さまざまな議論で直接的または間接的にほのめかした表記法を提案しますが、正式に書き留めることはありません。 意見があればコメントしてください。

数字間の区切り文字としての_の使用については、#28493(独立した提案)を参照してください。

Go 2のこの古い/棚上げされた議論を再検討する場合は、同時に8進数を検討することをお勧めします。 明らかに、 0123表記を削除することはできません(互換性の理由から-少なくとも非推奨期間がないわけではありません)が、 0bXXXを追加すると同時に0o123を追加することはできます0bXXX 。 これにより、より一貫性のある基数識別子のセットが可能になり、Goの構文とプログラマーの期待の優れた均一性が促進されます。

しかし、それ自体では、バイナリ提案はまだ価値があります。

baseが0の場合、 strconv.ParseIntは0b010構文をサポートしますか?

@nathanyはい、言語で0bプレフィックスをサポートすることにした場合は、ライブラリでもサポートする必要があります。 たとえば、コンパイラは現在、math / big.IntのSetStringメソッドに依存して定数リテラルをbig.Intsに変換します。したがって、SetString(およびstrconv.ParseIntなどの友人)も0bを理解することが期待されます。

おそらくそれほど明白ではないのは、これを#28493と一緒に受け入れる場合、ParseIntが_セパレーターもフィルタリングする必要があるかどうかです。 個別のパス( _をどこでも ` ) but for error handling (e.g.; do we allow _`に置き換えるかどうか)として簡単であり、ParseInt(および数値用の他のすべてのParseXXXルーチン)で処理する必要があるパフォーマンス)。

0o 8進リテラルについては、別の提案/問題があるべきですか、それともこれと一緒に保管する方がよいでしょうか?

0oはSwiftとRustに一致します。 この構文を好む理由を調べることができます。

0よりも0oを好む理由の1つは、 "012"がユーザー入力である可能性があるstrconv.ParseInt("012", 0, 64)とのあいまいさを回避するためです。 ただし、これが他の言語と同様にGoで大きな問題になるかどうかはわかりません。つまり、 Atoi常に基数10を使用し、Goにはデフォルトの引数がないため、プログラマーは明示的に派生するように要求する必要があります。基数に0を指定することにより、文字列プレフィックスから基数。

解析中の文字列で_を使用する必要があったとは言えません。 確かにあまり明白ではありません。

@nathany別の問題を提案します。 0bを許可することにした場合、一貫性を保つために0oも許可するのが理にかなっているかもしれないことに同意します(そして、gofmtに0接頭辞8進数を自動書き換えさせたい場合があります0oプレフィックス8進数。これにより、前者はコードベースから徐々に段階的に廃止されます)。 しかし、この提案は2進整数リテラルに関するものです。 それを維持しましょう。

元の質問に応答がなかったので、スレッド全体をもう一度読んで、スレッドの理由を確認しました
親指を立てるのがとても多いので、議論はほとんどありません。

これまでのところ、提案では次の理由でバイナリリテラルを要求しています。

他の言語はそれらを持っています

この提案では、他の言語がどのようにそれらを持っているか、そして他の言語がそれらにどのように慣れているかについて細心の注意を払っています。 これはこれまで十分な理由でしたか?

それらは「より読みやすい」

同意しません。 それらは1と0の卑劣なパターンであり、
base16への変換。

  • あなたはただ知っています

0b11101010対0xea。 何がターゲットになっているのかを考える必要はありません。
あなたが見てすぐにそれを知っています。

_最初の下位ビット、3番目の下位ビット、および5番目の下位ビットはオフですが、残りのビットはオフではありません。 そして、[ビットの総数を2回カウントして、数が正しいことを確認する] 8つあります。
合計ビット数。_

私はパターンが何であるかを知っています、そして私はおそらくそれを数秒間覚えているでしょう。 その知識はどうですか
本質的に便利ですか?

  • Go vs C ++

いくつかの議論は、おそらく意図せずに、彼らの利益を誤って伝えています。 の1つの特定の例では
このスレッドでは、goと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

問題は、GoがフォーマットされていないときにC ++が細心の注意を払って調整され、 constブロックがなく、16進数ではなく10進数が誤って使用されていることです(16進数を4桁に分割して2進数に簡単に変換することはできません)。 。

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

プロトコル仕様は時々バイナリを公開します

私を燃やした別の例は、組み込みプロトコルでアドレスを定義することでした
(I2C、SPI、> CANなど...)ここでは、多くの場合、バイナリ定数として定義されたアドレスがあります。
シフトされたデータシート>値の一部としてある種の読み取り/書き込みビットがあります。 変換
それらを16進数にすると、人間の脳が実行しなければならない翻訳の層がもう1つ追加され、したがってもう1つ追加されます。
デバッグ時に質問すること。

問題は、人間の脳がそもそもあなたのためにこれを行うべきではないということです。 |

デバッグの経験をもう一度考えてみてください。 2進整数リテラルをstderrまたはにダンプします
後でそれらのgrepを実行しますか? それぞれの1と言って、これらの番号を同僚と共有しますか?
と0大声で? あなたはむしろそれらを16進数で出力して送信する可能性があります、そしてそれが本当なら、それは
また、ソースコードは、必要性を排除するために、これらの数字を16進数で表現する必要があることも事実です。
人間の脳(またはプログラム)が読者のためにさらに多くの仕事をするために。

多くの仕様では、 1010は、これらの順序付けられた状態で構成されるビットストリームを意味すると表現しています。 これは、2進整数リテラルのバイト単位の概念に対応しておらず、期待している人を確実に焼き尽くします。
ビットストリームリーダーを実装します。 (バイナリ整数リテラルをサポートするよりも、標準ライブラリにビットストリームリーダーを実装したほうがいいです)。

今日、この機能の欠如に遭遇しました。 私の例のユースケースでは、整数の曜日を使用しています
日付のフィールド(0..6は日曜日..土曜日を意味します)および設定ビットマスクと照合します。
整数のソースはプログラムであるため、毎日の定数のセットを定義しません
今週の(私のコードには日曜日について具体的に話す理由がない)ので、1 << 3構文
ここでは役に立ちません。 ただし、プリファレンスビットマスクのデフォルト値が必要です。
おそらく0b0111110。 明らかに、このデフォルトを10進数(126)または16進数(0x7e)として記述するのは簡単ですが、
バイナリで書く方がかなり明確です。

曜日をエクスポートされていない定数として使用し、それらの値をORてマスクを作成します。 私は、2進整数リテラルが、この状況で何かをより明確にするのに役立つことに同意しません。

@asコメントありがとうございます。 記録されています。

明らかに、2進整数リテラルは必要ありません。 16進リテラルを使用してそのような数値を表現するためのかなり近い方法があります(そして私は私のブログ投稿で同じくらい指摘しました)。 しかし同時に、それらは多くのプログラマーにとっての問題点に対処しているように見えます。これは、言語に話す複雑さをあまり追加することなく、ここで簡単に修正できるものです。

おそらく、この問題について考えるより良い方法は、この点でGoを他のほとんどのプログラミング言語と同等にし、関連するすべてのベース(2、8、10、16)をサポートすることによって整数リテラル表現のセットを完成させるかどうかです。

これは、バイナリリテラルの有用性に関する個人的な感情とは別の質問であり、答えるのが簡単な場合があります。

変更https://golang.org/cl/152338はこの問題に言及しています: spec: add binary integer literals (tentative)

この提案に関連する仕様の変更については、 https://golang.org/cl/152338を参照して

変更https://golang.org/cl/152377はこの問題に言及しています: spec: permit underscores for grouping in numeric literals (tentative)

疑似乱数が0xff & (i ^ 0xab)として設定されているさまざまな種類のアルゴリズムのベンチマークを探していました。 0b10101011ではなく0xab場合は、読みやすくなります。 Goにバイナリリテラルがなく、提案さえないことに驚いています...

@andrewmedこれは、2進整数リテラルの提案です。

了解、ありがとう

#19308、#12711、#28493、および#29008の組み合わせ提案をgolang.org/design/19308-number-literalsに投稿しました。

これは、ブログ投稿で概説されているプロセスに従う最初の提案であることに注意してください。Go1.13サイクルの開始時(2月1日)にすべての準備が整い、チェックインします。次の3か月はそれらを使用します。機能と実際の使用状況に基づいたフィードバックの要請、そしてリリースフリーズの開始時(5月1日)に、Go1.13に作業を含めるかどうかについて「リリース決定」を行います。

フィードバックとGoの改善にご協力いただきありがとうございます。

もともと@rscによって私に提案されました:16進数の0Xを非推奨(ただしサポート)してから、0B(不要)と0O(不要、混乱、読みにくい)を追加しないのが賢明かもしれません。

@robpike ...そしてgofmtに0Xから0xへの変更を開始させます。

@josharian 、ええ、私も8進数(0644-> 0o644)でそれを取り上げましたが、少なくとも8進数の場合、go.modで宣言された最小言語バージョンを知っているgoimportsでしか実際にそれを行うことができませんでしたそのモジュールのコード。

しかし、0X-> 0xの場合は、gofmtで実行できます。

私は0B対0bおよび0O対0oについて強い感情を持っていません(多くのコードエディターは、大文字のOとは異なって見えるスラッシュでゼロを書き込みます。個人的には常に小文字を使用します)。

しかし、これらの新しいフォーマットを追加する主なポイントは、他の言語と互換性があり、そのような言語から来る人々の苦痛を和らげること、そしておそらく他の場所から来るコードを翻訳することです。 上記の人またはコードがこれらのプレフィックスに大文字を使用していて、Goが結局これらのリテラルを消化できなかった場合、その目的は無効になります。

また、Eとe(および新たにPとp)を許可する指数とは少し矛盾することにも注意してください。

要するに、私は感情を完全に支持しますが、大文字の0Bを許可しないことは、とにかく小文字の0bに慣れている人々を助けず(私が推測している大多数です)、他の人を傷つける不当な違いのようです。

一方、gofmtに自動的に(または-sを使用して)変更を行わせるのは良い考えのようです。

個々のビットとビットマスクを頻繁に扱う組み込み開発者として、バイナリリテラルは歓迎すべき変更です。 私は最近(GC)Cでそれらを発見し、嬉しい驚きを覚えました。
もちろん、ほとんどの人が0x1 、 0x80 、 0x8000を合理的にすばやく理解できます。 しかし、 0x1cようなものはあなたを一時停止させます。 もちろん、 (7 << 2)が少し優れています。0b00011100の方が読みやすく、意味を伝えます。つまり、3つの連続するビットが左側に2つあり、より明確になります。

変更https://golang.org/cl/157677はこの問題に言及しています: cmd/compile: accept new Go2 number literals

変更https://golang.org/cl/159997はこの問題に言及しています: go/scanner: accept new Go2 number literals

変更https://golang.org/cl/160018はこの問題に言及しています: cmd/gofmt: test that Go 2 number literals can be formatted

変更https://golang.org/cl/160239はこの問題に言及しています: go/constant: accept new Go2 number literals

変更https://golang.org/cl/160240はこの問題に言及しています: go/types: add tests for new Go 2 number literals

変更https://golang.org/cl/160247はこの問題に言及しています: fmt: scan new number syntax

変更https://golang.org/cl/160250はこの問題に言及しています: math/big: add %#b and %O integer formats

変更https://golang.org/cl/160248はこの問題に言及しています: text/template: accept new number syntax

変更https://golang.org/cl/160246はこの問題に言及しています: fmt: format 0b, 0o prefixes in %#b and %O

変更https://golang.org/cl/160244はこの問題に言及しています: strconv: add 0b, 0o integer prefixes in ParseInt, ParseUint

変更https://golang.org/cl/160184はこの問題に言及しています: cmd/gofmt: normalize number prefixes and exponents

変更https://golang.org/cl/160478はこの問題に言及しています: design/19308-number-literals: add note about gofmt

念のため、ブログ投稿blog.golang.org/go2-here-we-comeで、これらのGo2関連の言語変更の新しいプロセスを紹介しました。 提案を暫定的に受け入れ、サイクルの開始時に土地を変更し、それを使用した経験を積み、3か月後の凍結時に最終的な受け入れ決定を行います。 Go 1.13の場合、これは、ツリーが2月に開いたときに変更を着陸させ、5月にツリーがフリーズしたときに最終決定を行うことを意味します。

Go 1.13のこの提案を暫定的に受け入れ、ツリーが開いたときにその実装を開始する予定です。 「暫定承認」の発行状態は、提案-承認済みとマークされますが、開いたままになり、Goリリース(ここではGo1.13)にマイルストーンされます。 フリーズ時に問題を再検討し、最終的に受け入れられた場合はクローズします。

変更https://golang.org/cl/161098はこの問題に言及しています: spec: document new Go2 number literals

変更https://golang.org/cl/161199はこの問題に言及しています: text/scanner: accept new Go2 number literals

変更https://golang.org/cl/163079はこの問題に言及しています: text/scanner: don't liberally consume (invalid) floats or underbars

変更https://golang.org/cl/173663はこの問題に言及しています: unicode/utf8: use binary literals

変更https://golang.org/cl/174897はこの問題に言及しています: cmd/compile: disable Go1.13 language features for -lang=go1.12 and below

念のため、ブログ投稿blog.golang.org/go2-here-we-comeで、これらのGo2関連の言語変更の新しいプロセスを紹介しました。 Go 1.13の開発サイクルはこれで終わり、最終決定の時が来ました。

Go 2番号の文字通りの変更に関するフィードバックは非常に肯定的であり、否定的な意見はほとんどありません。 これらの変更により、言語に大きな複雑さを加えることなく、Goの数値リテラル構文が最新化および調和されます。3つの一般的な10進数以外の数値ベースに統一されたプレフィックス表記があり、他の最新のプログラミング言語で使用されている表記と一致します。 16進浮動小数点リテラルの導入は、数値コードに関心を持つ人々の問題点に対処します。 接尾辞「i」を任意の(非虚数)リテラルとともに使用して、均一な方法で虚数定数を作成できるようになりました。 そして最後に、アンダースコアを使用して、より長いリテラルを数字のグループに分割し、読みやすさを向上させることができます。

Go1.13の提案が承認されました。 変更が反映されたため、終了します。

-提案レビュー用のrsc

変更https://golang.org/cl/189718はこの問題に言及しています: compiler: support new numeric literal syntax

このページは役に立ちましたか?
0 / 5 - 0 評価