Goが適切に設計されたプログラミング言語である理由

翻訳として発行された囲ofに対する最近の批判で、トゥクナックはロブ・パイクに過度に精通していることに加えて、この言語に関するいくつかの興味深い点を持ち出しました。 悲しいかな、この記事の形式はトピックを整理したいという願望を意味するものではなかったので、ホリバーを再燃させるために、この記事で声に出した「問題」を乗り越えて、それが本当に何であり、現代企業がGoを選択する理由を理解することを提案します。



画像





理由#1。 スライスの操作は嫌です



著者は言語設計に関する彼の記事を、Pythonのような負のインデックスは機能しないというステートメントから始めています。

// Pythonの数字[:-1]は機能しません。


ここでの答えは簡単です-GoはPythonではなく、これらは異なる言語です。 Python以外の言語はPythonではないという事実を一部の人々に伝えることは困難ですが、問題をさらに詳しく調べてみましょう。 Goに負のインデックスが存在しない理由に関するRobert Pikeの公式の回答を次に示します。

式s [i:j]は、jがゼロより小さくなると、誤って誤った結果を返す可能性があるため、これは意図的に削除されました。 ところで、それがリートベルトの恐ろしいバグの理由でした。 インデックスは負であってはなりません。




Githubの問題には、次のステートメントを補完する同様の質問と回答があります。

この機能(たとえばPythonにあります)は意図的に欠落しています。

スライスにインデックスがある算術演算は、逆インデックスとして誤った負の結果が「うまくいった」場合に問題を引き起こす可能性があります。 これは微妙なバグにつながります。



さらに、現状から、読みやすさが勝ちます。 式s [:i]が長さiバイトのsからスライスを作成することは明らかです。 iが負になる可能性がある場合、スライスの表現全体を理解するには、より多くのコンテキストが必要です。



この決定は、微妙な構文上のトリックを避けるというGoの一般的な哲学に基づいています。


誰かにとって、負のインデックスは彼の場合に便利であり、記録では少し短いことに同意することができます。 しかし、Goの著者は、半世紀以上の開発経験に基づいて、ある場合には数バイトを節約し、別の場合には複雑なバグや読みやすさをもたらすことは価値がないと考えており、言語の概念により適したソリューションを選択しています。 Pythonプログラマーには少し慣れる必要があるが、長期的には厄介なエラーのリスクを減らすソリューション。 誰もが長期的に考えているわけではないことは明らかであり、そのため混乱が生じています。



さらに、著者の次の暴言:

/数字を挿入しますか? 大丈夫です

// Goには一般的に受け入れられているベストプラクティスがあります!

数字=追加(数字[:2]、追加([] int {3}、数字[2:] ...)...)



まず、これはベストプラクティスではありませんが、Go Slice Tricksページにあるワンライナースニペットです。 実際のコードでは、誰かがこれを行うと、読みやすくなります。 そして、ここで、最初に、Goでのスライスと配列の設計は、最終設計に至る前に1年以上にわたって議論されたことを思い出してください。 そして、主な要因は「実用的な必要性」と「速度」でした。 はい、これはあまり馴染みのないアプローチです。他の多くの言語では、機能の存在が優先されますが、Goではこのようになっています。



それでは、著者に2つの質問をしてみましょう。

  1. 配列の中央に要素を挿入するのはどれくらい一般的ですか?
  2. 配列の中央への挿入はどれくらい効率的ですか?


現在の実装(Goの配列はCの配列に非常に似ており、主にスライスのストレージとして機能します)では、この挿入はかなり高価な操作であり、メモリの割り当て(再)を強制すること、およびこれを使用する実際のケースを説明する価値はないと思いますたとえば、要素をスライスに「追加」するほど頻繁ではありません。

少なくともGoが設計されているニッチでは、これは実際には頻繁なケースではありません。 もちろん、そのような場合もあります。たとえば、バイナリプロトコルを使用した操作ですが、これは少なくとも1日に1回、または1か月に1回も書くようなものではありません。 著者の投稿に対するコメントの中で、少なくとも1人に、実際のコードから3つの例を提供するように依頼しました。彼は、配列の中央に要素を挿入する必要があります。 しかし、彼らは、配列ではなく、より適切なデータ構造を使用する方がはるかに正しいケースを発明しました。



要約-このような設計は、データ構造を正しく使用するインセンティブを作成し、長期的に抑制されたソフトウェアの形でレガシーを取得しないために、意図的に選択されました。 繰り返しになりますが、この「長期」は、多くの人々に嫌われており、ストーリー全体を台無しにします。



スライスに関する残りのコメントは分析しませんが、「これはスペイン語で文字Hを書く方法です-どのような恐怖を見てください」というレベルにあります。



理由番号2。 ヌルインターフェイスは常にゼロではありません:)



これは古典的なチェリーピッキングの例です-著者は、Goのインターフェイスに慣れていない初心者を混乱させるコードの例をインターネット上で見つけ(以前の記事のほとんどの読者が信じている)、この例を「貧弱なデザイン」として公開します。 もちろん、舞台裏に残されている唯一のことは、GoページのFAQのエントリがこの問題に当てられていること、実際のコードでこの問題に遭遇することは決してないことです(完全に思慮がない場合は後輩でない限り)、そして型システムとインターフェースの設計そのシンプルさと整合性により、クラスと継承を使用せずに複雑な抽象化を作成できます。 これはすべて著者と彼の読者によって渡され、「ついに囲Goについての憎悪の投稿」と熱心に書いています。



インターフェイスはGoではかなりユニークな概念であり、多くの新参者はそれらを理解するのに少し(しかし実際には「少し」)時間を必要とします。 そして、nil-interfaceの概念も。 これは、コンセプトの力をすべて無視して、それを悪いデザインと呼ぶ理由ではありません。 Goは、入力が迅速かつ無痛であるために既に多くのことを行っていますが、新しい概念を理解するのに労力を必要としないのは愚かなことです。



要約-インターフェースの設計は素晴らしく、平均的なプログラマーが聞いたこともない分野からの100の妥協に基づいています。 どのデザインでも、最初は混乱する可能性のあるものが常に小さいか、またはあまりありません。 しかし、Goでは、これは実際に遭遇する可能性が最も低い唯一の些細なことであり、実際に遭遇すると、公式FAQですぐに答えが見つかり、再び間違えられることはありません。 このようなことを自慢できる言語はほとんどありません。これは、Goの設計が優れていると考えられていることを示す明確な証拠の1つです。



理由番号3。 面白い隠し変数



ここで、著者は読者と彼自身の両方を欺いています。 まず、シャドウイングは常にさまざまな混乱誤解の原因であり、Goでは、たとえばC ++とは異なり、変数を非表示にするときの未定義の動作はありません。 プログラマーの不注意を非難することはできますが、もちろん、プログラマーがそのような間違いをしないように支援する責任の言語を緩和することはありません。

第二に、「変数の隠蔽の設計」に対する批判は、より成功した代替設計の提案を意味するはずです。その場合、議論は実質的である可能性があります。

第三に、標準のgo vetユーティリティは隠し変数宣言を表示できますが、非表示はエラーではないため、デフォルトではこのgo vetフラグはオフになっており、正しいコードで出力が詰まらないようになっています。

使用する
go tool vet -shadow=true
      
      



.



, go vet :


$ go tool vet -shadow=true main.go
main.go:16: declaration of number shadows declaration at main.go:10:

      
      





, — , , .



, Go, , , Go, .



№4. []struct []interface



, Go, . , , -, .

, , , , , « Go » (), .

, — «» «» Go. , , , «» . , , — .

— — , — . O(n) Go , . — , , , . , Go long term. , , .



№5. « »



, range , , , ,
range — foreach ++
, , , , .



? Go — , C++. Go Python, C++ — .

, go-tour ":=", :

for number := range numbers {}
      
      







, , range , foreach, . , . « » — , .



№6.



, , Go . , , opinionated Go , , FAQ, . , /C++, , , 5-10 , . , — , Go- , ++- , / « ». .

, , Go. . , , .



« , — = » , , .



№7. Go



Mozilla ( « , »), . :

, Go —


, , - -.



go generate , Make- , - yacc, thrift, protobuf swig. , , , , go generate (- hashbang). .



, . , , .

« , », «» « ».





Go — opinionated. Go , . — , — , — , — .

Go — , , . , , — , . , , , long-term short-term .



, Go - - , , . Go , . , , .



, «» — , , , . , , . , , , . , , Go , , , « REST- C++ 2 rock-star C++ » « Go » , , . , , , , « , ». .



, — , .



All Articles