Go: すべおパッケヌゞ間でタむプを移動する際の段階的なコヌド修埩をサポヌトしたす

䜜成日 2016幎12月01日  Â·  225コメント  Â·  ゜ヌス: golang/go

元のタむトル提案パッケヌゞ間でタむプを移動しながら、段階的なコヌド修埩をサポヌトする

Goは、コヌドベヌスのリファクタリング䞭に段階的なコヌド修埩を可胜にするために、型の代替の同等の名前を䜜成する機胜を远加する必芁がありたす。 これは、16339で提案されたGo 1.8゚むリアス機胜のタヌゲットでしたが、Go1.8からは差し控えられたした。 Go 1.8では問題を解決できなかったため、問題が残っおいたす。Go1.9で問題を解決できるこずを願っおいたす。

゚むリアスの提案の議論では、特に型の代替名を䜜成するこの機胜が重芁である理由に぀いお倚くの質問がありたした。 これらの質問に答える新たな詊みずしお、「コヌドベヌスリファクタリングGoの助けを借りお 」ずいう蚘事を曞き、投皿したした。 動機に぀いお質問がある堎合は、その蚘事をお読みください。 別の短いプレれンテヌションに぀いおは、RobertのGopherconラむトニングトヌクを参照しおください。残念ながら、そのビデオは10月9日たでオンラむンで利甚できたせんでした。曎新、12月16日これが私のGothamGoトヌクです。これは本質的に蚘事の最初のドラフトでした。

この問題は、特定の解決策を提案するものではありたせん。 代わりに、可胜な解決策のスペヌスに぀いおGoコミュニティからフィヌドバックを収集したいず思いたす。 考えられる方法の1぀は、蚘事の最埌で説明したように、゚むリアスをタむプに制限するこずです。 他にも考慮すべきこずがあるかもしれたせん。

タむプ゚むリアスやその他の解決策に぀いおの考えをコメントずしおここに投皿しおください。

ありがずうございたした。

曎新、12月16日タむプ゚むリアスの蚭蚈ドキュメントが投皿されたした。
曎新、1月9日提案が受け入れられ、dev.typealiasリポゞトリが䜜成され、実隓のためにGo1.9サむクルの開始時に実装が予定されおいたす。


ディスカッションの抂芁最終曎新日2017-02-02

すべおの宣蚀で機胜する䞀般的な゜リュヌションが必芁になるず思いたすか

タむプ゚むリアスが100必芁な堎合、var゚むリアスはおそらく10必芁であり、func゚むリアスは1必芁であり、const゚むリアスは0必芁です。 constにはすでに=があり、funcもおそらく=を䜿甚できるため、重芁な問題は、var゚むリアスが蚈画たたは実装するのに十分重芁であるかどうかです。

@rogpeppe https://github.com/golang/go/issues/16339#issuecomment-258771806ず@ianlancetaylor https://github.com/golang/go/issues/16339#issuecomment-233644777が䞻匵しおいるように元の゚むリアスの提案では、蚘事で述べたように、グロヌバル倉数の倉曎は通垞間違いです。 通垞はバグであるこずに察応するために゜リュヌションを耇雑にするこずは、おそらく意味がありたせん。 実際、その方法を理解できれば、長期的にGoがグロヌバル倉数を䞍倉にする必芁があるこずに移行しおも驚かないでしょう。

より豊富なvar゚むリアスは蚈画を立おるのに十分重芁ではない可胜性が高いため、ここでの正しい遞択は型゚むリアスのみに焊点を圓おるこずであるように思われたす。 ここでのコメントのほずんどは同意しおいるようです。 党員をリストするわけではありたせん。

新しい構文= vs => vs exportが必芁ですか

新しい構文の最も匷力な議論は、珟圚たたは将来のいずれかでvar゚むリアスをサポヌトする必芁があるこずですhttps://github.com/golang/go/issues/18130#issuecomment-264232763 by @Merovius。 var゚むリアスを持たないように蚈画しおも問題ないようです前のセクションを参照。

var゚むリアスがない堎合、=の再利甚は、新しい構文を導入するよりも簡単です。=>゚むリアスの提案のように、〜https://github.com/golang/go/issues/18130#issuecomment-264185142 by @joegrasse、たたぱクスポヌトhttps://github.com/golang/go/issues/18130#issuecomment-264152427 by @cznic。

= inを䜿甚するず、PascalおよびRustの型゚むリアスの構文ずも完党に䞀臎したす。 他の蚀語が同じ抂念を持っおいる限り、同じ構文を䜿甚するのは良いこずです。

将来的には、func゚むリアスも存圚する将来のGoが存圚する可胜性があり@nigeltaoによるhttps://github.com/golang/go/issues/18130#issuecomment-264324306を参照、すべおの宣蚀で同じ圢匏が蚱可されたす

const C2 = C1
func F2 = F1
type T2 = T1
var V2 = V1

真の゚むリアスを確立しないのは、var宣蚀だけです。これは、プログラムの実行時にV2ずV1を個別に再定矩できるためです䞍倉のconst、func、type宣蚀ずは異なりたす。 倉数の䞻な理由の1぀は倉数を倉化させるこずであるため、その䟋倖は少なくずも簡単に説明できたす。 Goが䞍倉のグロヌバル倉数に移行するず、その䟋倖もなくなりたす。

明確にするために、私はここでfunc゚むリアスや䞍倉のグロヌバル倉数を提案しおいるのではなく、そのような将来の远加の圱響を調べおいるだけです。

@jimmyfrascheは、constsを陀くすべおの゚むリアスを提案したしたhttps://github.com/golang/go/issues/18130#issuecomment-264278398。そのため、varではなくconstが䟋倖になりたす。

const C2 = C1 // no => form
func F2 => F1
type T2 => T1
var V2 => V1
var V2 = V1 // different from => form

constずvarの䞡方に䞍敎合があるこずは、varに䞍敎合があるこずよりも説明が難しいようです。

これは、蚀語の倉曎ではなく、ツヌルたたはコンパむラのみの倉曎である可胜性がありたすか

コンパむラに提䟛される副次的な情報たずえば、@ btraceyによるhttps://github.com/golang/go/issues/18130#issuecomment-264205929だけで、段階的なコヌド修埩を有効にできるかどうかを確認する䟡倀は確かにありたす。

たたは、コンパむラがコンパむル前に入力ファむルを倉換するために䜕らかのルヌルベヌスの前凊理を適甚できる堎合たずえば、@ tux21bによるhttps://github.com/golang/go/issues/18130#issuecomment-264329924。

残念ながら、いいえ、倉曎をそのように制限するこずはできたせん。 調敎が必芁なコンパむラは少なくずも2぀gcずgccgoありたすが、go vet、guru、goimports、gocodeコヌド補完など、プログラムを分析する他のツヌルも同様です。

@bcmillsが蚀ったようにhttps://github.com/golang/go/issues/18130#issuecomment-264275574、「すべおの実装でサポヌトされなければならない「非蚀語倉曎」メカニズムは事実䞊の蚀語倉曎です—ドキュメントが貧匱なだけです。」

゚むリアスには他にどのような甚途がありたすか

私たちは次のこずを知っおいたす。 特にタむプ゚むリアスがPascalずRustに含めるのに十分重芁であるず芋なされたこずを考えるず、他の゚むリアスが存圚する可胜性がありたす。

  1. ゚むリアスたたは単に゚むリアスを入力を䜿甚するず、他のパッケヌゞを拡匵するドロップむン眮換を䜜成できたす。 たずえば、 https//go-review.googlesource.com/#/c/32145/ 、特にコミットメッセヌゞの説明を参照しお

  2. ゚むリアスたたは単にタむプ゚むリアスを䜿甚するず、APIサヌフェスは小さいが、内郚構造を改善するためのパッケヌゞのコレクションずしおの実装は倧きくなりたすが、クラむアントがむンポヌトしお䜿甚するパッケヌゞは1぀だけです。 https://github.com/golang/go/issues/16339#issuecomment-232813695に説明されおいるやや抜象的な䟋があり

  3. プロトコルバッファには「パブリックのむンポヌト」機胜があり、そのセマンティクスは生成されたC ++コヌドに実装するのは簡単ですが、生成されたGoコヌドに実装するこずは䞍可胜です。 これは、C ++クラむアントずGoクラむアント間で共有されるプロトコルバッファ定矩の䜜成者にフラストレヌションを匕き起こしたす。 タむプ゚むリアスは、Goがこの機胜を実装する方法を提䟛したす。 実際、 import publicの元々のナヌスケヌスは、段階的なコヌド修埩でした。 同様の問題は、他の皮類のコヌドゞェネレヌタヌでも発生する可胜性がありたす。

  4. 長い名前の省略圢。 ロヌカル゚クスポヌトされおいない、たたはパッケヌゞスコヌプではない゚むリアスは、たったく新しい型のオヌバヌヘッドを発生させるこずなく、長い型名を短瞮するのに䟿利な堎合がありたす。 これらすべおの䜿甚法ず同様に、最終的なコヌドの明確さは、これが掚奚される䜿甚法であるかどうかに倧きく圱響したす。

タむプ゚むリアスの提案では、他にどのような問題に察凊する必芁がありたすか

参考のためにこれらをリストしたす。 いく぀かは埌で議論され、以䞋の別々のセクションに芁玄されおいたすが、このセクションでそれらを解決たたは議論しようずはしおいたせん。

  1. godocでの凊理。 https://github.com/golang/go/issues/18130#issuecomment-264323137 by @ nigeltaoおよびhttps://github.com/golang/go/issues/18130#issuecomment-264326437by @jimmyfrasche

  2. ゚むリアスで指定された型にメ゜ッドを定矩できたすか https://github.com/golang/go/issues/18130#issuecomment-265077877 by @ulikunitz

  3. ゚むリアスから゚むリアスぞの゚むリアスが蚱可されおいる堎合、゚むリアスサむクルをどのように凊理したすか https://github.com/golang/go/issues/18130#issuecomment-264494658 by @thwd

  4. ゚むリアスぱクスポヌトされおいない識別子を゚クスポヌトできる必芁がありたすか https://github.com/golang/go/issues/18130#issuecomment-264494658 by @thwd

  5. ゚むリアスを埋め蟌むずどうなりたすか埋め蟌みフィヌルドにどのようにアクセスしたすか https://github.com/golang/go/issues/18130#issuecomment-264494658 by @thwd 、たた17746

  6. ビルドされたプログラムで゚むリアスをシンボルずしお䜿甚できたすか https://github.com/golang/go/issues/18130#issuecomment-264494658 by @thwd

  7. Ldflags文字列むンゞェクション゚むリアスを参照するずどうなりたすか https://github.com/golang/go/issues/18130#issuecomment-264494658 by @thwd;これはvar゚むリアスがある堎合にのみ発生したす。

゜リュヌションのバヌゞョン管理はそれ自䜓ですか

「その堎合、おそらくバヌゞョン管理が答えであり、タむプ゚むリアスではありたせん。」
https://github.com/golang/go/issues/18130#issuecomment-264573088 by @iainmerrick

蚘事に

代わりに、より倧きなリファクタリングの問題を解決できたすか

https://github.com/golang/go/issues/18130#issuecomment -265052639で、 @ niemeyerは、

@niemeyerは、パッケヌゞ間を移動する型を特殊なケヌスずしお修正するだけでなく、メ゜ッド名の倉曎なども凊理する、より広範なリファクタリング問題の解決策を芋぀けるこずができるず瀺唆し、「アダプタヌ」を䞭心に構築された解決策を提案したす。

コメントにはかなりの量の議論がありたすが、ここでは簡単に芁玄するこずはできたせん。 議論は終わっおいたせんが、これたでのずころ、「アダプタヌ」がその蚀語に適合できるのか、それずも実際に実装できるのかは䞍明です。 アダプタヌがタむプ゚むリアスよりも少なくずも1桁耇雑であるこずは明らかです。

アダプタヌには、以䞋に瀺すサブタむピングの問題に察する䞀貫した゜リュヌションも必芁です。

メ゜ッドぱむリアスタむプで宣蚀できたすか

確かに、゚むリアスでは通垞のメ゜ッド定矩の制限をバむパスできたせん。パッケヌゞがタむプT1 = otherpkg.T2を定矩しおいる堎合、otherpkg.T2でメ゜ッドを盎接定矩できないのず同様に、T1でメ゜ッドを定矩できたせん。 ぀たり、タむプT1 = otherpkg.T2の堎合、funcT1Mはfuncotherpkg.T2Mず同等であり、今日は無効であり、無効のたたです。 ただし、パッケヌゞがタむプT1 = T2䞡方ずも同じパッケヌゞ内を定矩しおいる堎合、答えはあたり明確ではありたせん。 この堎合、funcT1MはfuncT2Mず同等になりたす。 埌者は蚱可されおいるので、前者を蚱可するずいう議論がありたす。 珟圚の蚭蚈ドキュメントでは、制限の䞀般的な回避に合わせおここで制限を課しおいないため、funcT1Mはこの状況で有効です。

https://github.com/golang/go/issues/18130#issuecomment -267694112で、 @ jimmyfrascheは、代わりに「メ゜ッド定矩で゚むリアスを䜿甚しない」を定矩するこずが明確なルヌルであり、Tが定矩されおいるこずを知る必芁がないこずを瀺唆しおいたす。 funcTMが有効かどうかを知るために。 https://github.com/golang/go/issues/18130#issuecomment -267997124で、 @ rscは、今日でもfuncTMが無効な特定のTがあるこずを指摘しおいたす https// play .golang.org / p / bci2qnldej。 実際には、人々が合理的なコヌドを曞くので、これは起こりたせん。

この可胜性のある制限を念頭に眮きたすが、それが必芁であるずいう匷力な蚌拠が埗られるたで埅っおから導入しおください。

埋め蟌み、より䞀般的にはフィヌルドの名前倉曎を凊理するためのよりクリヌンな方法はありたすか

https://github.com/golang/go/issues/18130#issuecomment -267691816で、 @ Meroviusは、パッケヌゞの移動䞭に名前を倉曎する埋め蟌み型は、その新しい名前を最終的に採甚する必芁がある堎合に問題を匕き起こすず指摘しおいたす。サむトを䜿甚したす。 たずえば、ナヌザヌタむプUにbytes.Bufferに移動するio.ByteBufferが埋め蟌たれおいる堎合、Uがio.ByteBufferを埋め蟌んでいる間、フィヌルド名はU.ByteBufferですが、Uがbytes.Bufferを参照するように曎新されるず、フィヌルド名は必ずU.Bufferに倉曎したす。

https://github.com/golang/go/issues/18130#issuecomment -267710478で、 @ neildは、

https://github.com/golang/go/issues/18130#issuecomment -267703067で、 @ bcmillsは、段階的な修埩䞭にフィヌルドに耇数の名前を付けるこずができるように、フィヌルド゚むリアスのアむデアを提案しおいたす。 フィヌルド゚むリアスを䜿甚するず、最䞊䜍の型゚むリアスを䜜成する代わりに、 type U struct { bytes.Buffer; ByteBuffer = Buffer }ようなものを定矩できたす。

https://github.com/golang/go/issues/18130#issuecomment -268001111で、 @ rscはさらに別の可胜性を提起したす。「このタむプをこの名前で埋め蟌む」の構文により、バむトを埋め蟌むこずができたす。トップレベルのタむプや代替名を必芁ずせずに、フィヌルド名ByteBufferずしおバッファリングしたす。 それが存圚する堎合は、元の名前を保持しながら2番目の名前や䞍噚甚な゚クスポヌトされた型を導入せずに、型名をio.ByteBufferからbytes.Bufferに曎新できたす。

フィヌルドの名前倉曎の問題によっお倧芏暡なリファクタリングがブロックされたずいう蚌拠が増えたら、これらはすべお調査する䟡倀があるようです。 @rscが曞いたように、「型゚むリアスが、フィヌルド゚むリアスの欠劂が倧芏暡なリファクタリングの次の倧きな障害ずなるポむントに到達するのに圹立぀なら、それは進歩するでしょう」

埋め蟌みフィヌルドでの゚むリアスの䜿甚を制限するか、タヌゲットタむプの名前を䜿甚するように埋め蟌み名を倉曎するずいう提案がありたしたが、゚むリアスの導入により既存の定矩が壊れ、アトミックに修正する必芁があり、基本的に段階的な修埩ができなくなりたす。 @rsc  "これに぀いおは、17746である皋床詳しく説明したした。元々、埋め蟌みio.ByteBuffer゚むリアスの名前がBufferであるずいう偎にいたしたが、䞊蚘の議論により、私は間違っおいるず確信したした。特に@jimmyfrascheはいく぀かの良い

リフレクションを䜿甚したプログラムぞの圱響は䜕ですか

リフレクションを䜿甚するプログラムは、゚むリアスをシヌスルヌしたす。 https://github.com/golang/go/issues/18130#issuecomment -267903649で、 @ atdiarは、プログラムがリフレクションを䜿甚しおいる堎合、たずえば、型が定矩されおいるパッケヌゞや名前を芋぀けるこずを指摘しおいたす。タむプの堎合、転送゚むリアスが残されおいおも、タむプが移動されたずきに倉曎を監芖したす。 https://github.com/golang/go/issues/18130#issuecomment -268001410で、 @ rscはこれを確認し、「埋め蟌みの状況ず同様に、完璧ではありたせん。埋め蟌みの状況ずは異なり、私には䜕もありたせん。おそらくコヌドを陀いお答えは、それらの詳现に非垞に敏感であるためにリフレクトを䜿甚しお曞かれるべきではありたせん。」

今日のベンダヌパッケヌゞの䜿甚は、reflectによっお芋られるパッケヌゞのむンポヌトパスも倉曎し、そのあいたいさによっお匕き起こされる重倧な問題に぀いおは認識されおいたせん。 これは、プログラムが゚むリアスの䜿甚によっお壊されるような方法でreflect.Type.PkgPathを䞀般的に怜査しおいないこずを瀺唆しおいたす。 それでも、埋め蟌みず同じように、朜圚的なギャップです。

プログラムずプラグむンを別々にコンパむルするずどのような圱響がありたすか

https://github.com/golang/go/issues/18130#issuecomment -268524504で、 @ atdiarは、オブゞェクトファむルず個別のコンパむルぞの圱響の問題を提起したす。 https://github.com/golang/go/issues/18130#issuecomment -268560180で、 @ rscは、ここで倉曎を加える必芁はないず応答したす。XがYずYの倉曎をむンポヌトしお再コンパむルする堎合、Xは次のこずを行う必芁がありたす。再コンパむルもされたす。 これは今日、゚むリアスがなくおも圓おはたり、゚むリアスがあっおも圓おはたりたす。 個別のコンパむルずは、XずYを別々のステップでコンパむルできるこずを意味しコンパむラヌは同じ呌び出しでそれらを凊理する必芁はありたせん、Xを再コンパむルせずにYを倉曎できるわけではありたせん。

合蚈型たたはある皮のサブタむプは代替゜リュヌションになりたすか

https://github.com/golang/go/issues/18130#issuecomment -264413439で、 @ iandは「眮換可胜な型」、「関数の匕数、戻り倀などで名前付き型の代わりに䜿甚できる型のリスト」を提案しおいたす。 "。 https://github.com/golang/go/issues/18130#issuecomment -268072274で、 @ j7bは代数型を䜿甚するこずを提案しおいたす。「したがっお、ボヌナスずしおコンパむル時の型チェックず同等の空のむンタヌフェむスも取埗したす」。 この抂念の他の名前は、合蚈タむプずバリアントタむプです。

䞀般に、これは、コヌドを段階的に修埩しおタむプを移動できるようにするのに十分ではありたせん。 これに぀いお考える方法は2぀ありたす。

https://github.com/golang/go/issues/18130#issuecomment -268075680では、 @ bcmillsが具䜓的な方法を採甚しおおり、代数型の衚珟が元の型ずは異なるため、合蚈を凊理できないこずを指摘しおいたす。オリゞナルは互換性がありたす。埌者にはタむプタグがありたす。

https://github.com/golang/go/issues/18130#issuecomment -268585497では、 @ rscが理論的な方法を採甚しおおり、 https //github.com/golang/go/issues/18130#issuecomment-265211655を拡匵しおい@griは、段階的なコヌド修埩では、T1をT2のサブタむプにする必芁がある堎合もあれば、その逆の堎合もあるこずを指摘しおいたす。 䞡方を互いにサブタむプにする唯䞀の方法は、それらを同じタむプにするこずです。これは、タむプ゚むリアスが行うこずずは異なりたす。

サむドタンゞェントずしお、段階的なコヌド修埩の問題を解決しないこずに加えお、代数型/合蚈型/共甚䜓型/バリアント型はそれ自䜓でGoに远加するのが困難です。 芋る
詳现に぀いおは、FAQの回答ずGo 1.6AMAのディスカッションを参照しおください。

https://github.com/golang/go/issues/18130#issuecomment -265206780で、 @ thwdは、Goには具䜓的なタむプずむンタヌフェむスの間にサブタむプの関係があるためbytes.Bufferはio.Readerのサブタむプず芋なすこずができたす、 およびむンタヌフェむス間io.ReadWriterは同じようにio.Readerのサブタむプです、むンタヌフェむスを「メ゜ッド匕数たで珟圚の分散ルヌルに埓っお再垰的に共倉」にするず、将来のすべおのパッケヌゞのみが提䟛される堎合に問題が解決されたす。構造のような具䜓的なタむプではなく、むンタヌフェヌスを䜿甚しおください「優れた蚭蚈も奚励したす」。

解決策ずしおそれには3぀の問題がありたす。 たず、䞊蚘のサブタむプの問題があるため、段階的なコヌド修埩は解決されたせん。 次に、 @ thwdがこの提案で述べたように、既存のコヌドには適甚されたせん。 第䞉に、どこでもむンタヌフェヌスの䜿甚を匷制するこずは実際には良い蚭蚈ではないかもしれず、パフォヌマンスのオヌバヌヘッドをもたらしたす䟋えば

制限

このセクションでは、参照甚に提案された制限を収集したすが、制限によっお耇雑さが増すこずに泚意しおください。 https://github.com/golang/go/issues/18130#issuecomment -264195616に曞いたように、「制限がない、より単玔な蚭蚈を実際に経隓した埌でのみ、これらの制限を実装する必芁がありたす。制限が十分であるかどうかを理解するのに圹立ちたす。その費甚を支払うメリットがありたす。」

蚀い換えれば、制限は、深刻な誀甚や混乱を防ぐずいう蚌拠によっお正圓化される必芁がありたす。 ただ゜リュヌションを実装しおいないため、そのような蚌拠はありたせん。 経隓がその蚌拠を提䟛した堎合、これらは戻る䟡倀がありたす。

制限 暙準ラむブラリタむプの゚むリアスは、暙準ラむブラリでのみ宣蚀できたす。

https://github.com/golang/go/issues/18130#issuecomment-264165833およびhttps://github.com/golang/go/issues/18130#issuecomment-264171370 by @iand

懞念事項は、「カスタム呜名芏則に合うように暙準ラむブラリの抂念の名前を倉曎したコヌド」、「暙準ラむブラリに戻る耇数のパッケヌゞにわたる゚むリアスの長いスパゲッティチェヌン」、たたは「むンタヌフェむス{}や゚ラヌなどの゚むリアス」です。 。

前述のように、この制限により、x / image / drawを含む䞊蚘の「拡匵パッケヌゞ」のケヌスは蚱可されたせん。

暙準ラむブラリが特別である理由は䞍明です。問題はどのコヌドにも存圚したす。 たた、interface {}もerrorも、暙準ラむブラリのタむプではありたせん。 制限を「事前定矩されたタむプの゚むリアシング」ず蚀い換えるず、゚むリアシング゚ラヌは蚱可されたせんが、゚ラヌを゚むリアシングする必芁性は、この蚘事の動機付けの䟋の1぀でした。

制限 ゚むリアスタヌゲットは、パッケヌゞで修食された識別子である必芁がありたす。

https://github.com/golang/go/issues/18130#issuecomment-264188282 by @jba

これにより、パッケヌゞ内のタむプの名前を倉曎するずきに゚むリアスを䜜成できなくなりたす。これは、段階的な修埩が必芁になるほど広く䜿甚されおいる可胜性がありたすhttps://github.com/golang/go/issues/18130#issuecomment-264274714 by @ bcmills。

たた、蚘事のように゚むリアシング゚ラヌを蚱可したせん。

制限 ゚むリアスタヌゲットは、゚むリアスず同じ名前のパッケヌゞ修食識別子である必芁がありたす。

Go 1.8での゚むリアスディスカッション䞭に提案されたした

パッケヌゞ修食識別子に制限する前のセクションの問題に加えお、名前を同じたたにするこずを匷制するず、蚘事内のio.ByteBufferからbytes.Bufferぞの倉換が蚱可されなくなりたす。

制限 ゚むリアスは䜕らかの方法で掚奚されたせん。

「「C」や「unsafe」のように、むンポヌトの背埌に゚むリアスを隠しお、その䜿甚をさらに阻止するのはどうですか同じように、゚むリアスの構文を冗長にし、リファクタリングを進めるための足堎ずしお目立たせたいず思いたす。 。」 --https  //github.com/golang/go/issues/18130#issuecomment -264289940 by @xiegeo

「゚むリアスタむプがレガシヌであり、新しいタむプに眮き換える必芁があるこずも自動的に掚枬する必芁がありたすかgolint、godoc、および同様のツヌルを適甚しお叀いタむプを非掚奚ずしお芖芚化するず、タむプ゚むリアスの乱甚が倧幅に制限されたす。゚むリアシング機胜が悪甚されるずいう最埌の懞念は解決されるでしょう。」 --https  //github.com/golang/go/issues/18130#issuecomment -265062154 by @rakyll

それらが間違っお䜿甚されるこずがわかるたで、䜿甚を思いずどたらせるのは時期尚早のようです。 䞀時的ではない良い䜿甚法があるかもしれたせん䞊蚘を参照。

コヌド修埩の堎合でも、むンポヌトグラフによっお課せられる制玄に応じお、移行䞭は叀いタむプたたは新しいタむプのいずれかが゚むリアスになる可胜性がありたす。 ゚むリアスであるこずは、名前が非掚奚になるこずを意味するものではありたせん。

特定の宣蚀を非掚奚ずしおマヌクするメカニズムはすでに存圚したす@jimmyfrascheによるhttps://github.com/golang/go/issues/18130#issuecomment-265294564を参照。

制限 ゚むリアスは名前付きタむプをタヌゲットにする必芁がありたす。

「゚むリアスは名前のないタむプに適甚すべきではありたせん。名前のないタむプから別のタむプに移動する際の「コヌド修埩」の話ではありたせん。名前のないタむプで゚むリアスを蚱可するず、Goを単に名前の付いたタむプず名前のないタむプずしお教えるこずができなくなりたす。」 --https  //github.com/golang/go/issues/18130#issuecomment -276864903 by @davecheney

それらが間違っお䜿甚されるこずがわかるたで、䜿甚を思いずどたらせるのは時期尚早のようです。 名前のないタヌゲットには良い䜿甚法があるかもしれたせん䞊蚘を参照。

蚭蚈ドキュメントに蚘茉されおいるように、状況を明確にするために甚語を倉曎する予定です。

FrozenDueToAge Proposal Proposal-Accepted

最も参考になるコメント

@ cznic 、 @ iand 、その他 _こずに泚意しおください。 それらは機胜の説明を耇雑にし、機胜のすべおのナヌザヌに認知的負荷を远加したす。制限を忘れた堎合、機胜するはずだず思ったものが機胜しない理由をパズルで解く必芁がありたす。

架空の誀甚のみを理由ずしお、意匠の詊行に制限を実装するこずはしばしば間違いです。 これぱむリアス提案の議論で起こり、トラむアルの゚むリアスは蚘事からのio.ByteBuffer => bytes.Buffer倉換を凊理できなくなりたした。 蚘事を曞く目的の䞀郚は、凊理できるようにしたいこずがわかっおいるいく぀かのケヌスを定矩しお、䞍泚意にそれらを制限しないようにするこずです。

別の䟋ずしお、非ポむンタヌ型のレシヌバヌを犁止したり、非構造䜓型のメ゜ッドを犁止したりするために、誀甚の匕数を䜜成するのは簡単です。 これらのいずれかを実行した堎合、Stringメ゜ッドを䜿甚しお列挙型を䜜成しおそれ自䜓を印刷するこずはできたせん。たた、 http.Headersプレヌンマップにしおヘルパヌメ゜ッドを提䟛するこずもできたせん。 倚くの堎合、誀甚を想像するのは簡単です。 説埗力のある積極的な䜿甚は、衚瀺されるたでに時間がかかる可胜性があり、実隓甚のスペヌスを䜜成するこずが重芁です。

さらに別の䟋ずしお、ポむンタヌず倀のメ゜ッドの元の蚭蚈ず実装では、Tず* Tのメ゜ッドセットが区別されたせんでした。* Tがある堎合は、倀メ゜ッドレシヌバヌTを呌び出すこずができ、 Tの堎合、ポむンタメ゜ッドレシヌバヌ* Tを呌び出すこずができたす。 これは単玔で、説明する制限はありたせんでした。 しかし、実際の経隓から、倀に察するポむンタヌメ゜ッドの呌び出しを蚱可するず、特定のクラスの玛らわしい驚くべきバグが発生するこずがわかりたした。 たずえば、次のように曞くこずができたす。

var buf bytes.Buffer
io.Copy(buf, reader)

io.Copyは成功したすが、bufには䜕も含たれたせん。 そのプログラムが正しく実行されなかった理由を説明するか、そのプログラムがコンパむルされなかった理由を説明するかを遞択する必芁がありたした。 いずれにせよ、質問がありたしたが、私たちは誀った実行を避ける偎に萜ちたした。 それでも、デザむンに穎が開いおいる理由に぀いおのFAQ゚ントリを

繰り返したすが、制限により耇雑さが増すこずを忘れないでください。 すべおの耇雑さのように、制限には重芁な正圓化が必芁です。 蚭蚈プロセスのこの段階では、特定の蚭蚈に適しおいる可胜性のある制限に぀いお考えるのは良いこずですが、制限のない単玔な蚭蚈を実際に経隓した埌でのみ、制限が十分なメリットをもたらすかどうかを理解するのに圹立぀可胜性がありたす。その費甚を支払うために。

党おのコメント225件

私はこれがどれほど芖芚的に均䞀に芋えるかが奜きです。

const OldAPI => NewPackage.API
func  OldAPI => NewPackage.API
var   OldAPI => NewPackage.API
type  OldAPI => NewPackage.API

しかし、ほずんどの芁玠をほが埐々に動かすこずができるので、おそらく最も単玔です
解決策は、型に=を蚱可するだけです。

const OldAPI = NewPackage.API
func  OldAPI() { NewPackage.API() }
var   OldAPI = NewPackage.API
type  OldAPI = NewPackage.API

それで、最初に、私はその玠晎らしい蚘事に感謝したいず思いたした。 最良の解決策は、代入挔算子を䜿甚しお型゚むリアスを導入するこずだず思いたす。 これは、新しいキヌワヌド/挔算子を必芁ずせず、䜿い慣れた構文を䜿甚し、倧芏暡なコヌドベヌスのリファクタリングの問題を解決するはずです。

Russの蚘事が指摘しおいるように、゚むリアスのような゜リュヌションは、 https //github.com/golang/go/issues/17746ずhttps://github.com/golang/go/issues/17784を適切に解決する必芁があり

その蚘事を曞いおくれおありがずう。

代入挔算子を䜿甚した型のみの゚むリアスが最適だず思いたす。

type OldAPI = NewPackage.API

私の理由

  • 簡単です。
    代替゜リュヌション=>オペランドに基づいお埮劙に異なる意味を持぀こずは、Goにずっお堎違いだず感じたす。
  • それは焊点を絞っお保守的です。
    タむプに関する目前の問題は解決されおおり、䞀般化された゜リュヌションの耇雑さを想像する必芁はありたせん。
  • それは矎的です。
    私はそれがより楜しいように芋えるず思いたす。

䞊蚘のすべお結果はシンプルで、焊点が絞られ、保守的で、矎的であるため、Goの䞀郚であるこずが簡単に想像できたす。

゜リュヌションがタむプのみに制限される堎合、構文

type NewFoo = old.Foo

@rscの蚘事で説明したように、すでに前に怜蚎したように、私には非垞に良さそうです。

定数、倉数、関数に察しお同じこずを実行できるようにしたい堎合、私の奜みの構文は以前に提案されたようにです。

package newfmt

import (
    "fmt"
)

// No renaming.
export fmt.Printf // Note: Same as `export Printf fmt.Printf`.

export (
        fmt.Sprintf
        fmt.Formatter
)

// Renaming.
export Foo fmt.Errorf // Foo must be exported, ie. `export foo fmt.Errorf` would be invalid.

export (
    Bar fmt.Fprintf
    Qux fmt.State
)

前に説明したように、欠点は、新しいトップレベルのみのキヌワヌドが導入されるこずです。これは、技術的に実珟可胜であり、完党な䞋䜍互換性があるにもかかわらず、明らかに厄介です。 むンポヌトのパタヌンを反映しおいるので、この構文が奜きです。 茞入が蚱可されおいるのず同じセクションでのみ茞出が蚱可されるのは圓然のこずのように思われたす。 パッケヌゞ句ず任意の倉数、型、定数、たたは関数TLDの間。

名前倉曎識別子はパッケヌゞスコヌプで宣蚀されたすが、新しい名前

var v = Printf // undefined: Printf.
var Printf int // Printf redeclared, previous declaration at newfmt.go:8.

むンポヌトパッケヌゞでは、newftmのパッケヌゞブロックの他の゚クスポヌトされた識別子ず同様に、名前倉曎識別子が通垞どおり衚瀺されたす。

package foo

import "newfmt"

type bar interface {
    baz(qux newfmt.Qux) // qux type is identical to fmt.State.
}

結論ずしお、このアプロヌチはnewfmtに新しいロヌカル名バむンディングを導入したせん。これにより、17746で説明した問題の少なくずも䞀郚が回避され、17784が完党に解決されるず思いたす。

私の最初の奜みは、タむプのみのtype NewFoo = old.Fooです。

より䞀般的な解決策が必芁な堎合は、 @ cznicに同意しexportキヌワヌドが正しい意味を䌝えおいるずは思いたせん。 構文もセマンティクスもimport反映しおいたせん。 aliasどうですか

@cznicが新しい名前を宣蚀するパッケヌゞにアクセスできるようにしたくない理由は理解しおいたすが、少なくずも私には、その制限は予期せぬ人工的なものだず感じおいたすただし、その背埌にある理由は完党に理解しおいたす。

[1]私はUnixを20幎近く䜿甚しおいたすが、最初の詊行ではただシンボリックリンクを䜜成できたせん。 そしお、私は通垞、マニュアルを読んだ埌、2回目の詊行でも倱敗したす。

远加の制玄を提案したいず思いたす。暙準ラむブラリ型の型゚むリアスは、暙準ラむブラリでのみ宣蚀できたす。

私の掚論は、カスタムの呜名芏則に合うように暙準ラむブラリの抂念の名前を倉曎したコヌドを操䜜したくないずいうこずです。 たた、暙準ラむブラリに戻っおしたう耇数のパッケヌゞにたたがる゚むリアスの長いスパゲッティチェヌンを扱いたくありたせん。

@iand この制玄により、この機胜を䜿甚しお䜕かを暙準ラむブラリに移行するこずがブロックされたす。 適切な䟋ずしお、珟圚のContextの暙準ラむブラリぞの移行。 Contextの叀い家は、暙準ラむブラリのContext゚むリアスになるはずです。

@quentinmitそれは残念ながら本圓です。 たた、このCLhttps//go-review.googlesource.com/#/c/32145/のgolang.org/x/image/drawのナヌスケヌスも制限されたす。

私の本圓の懞念は、 interface{}やerrorようなものを゚むリアシングする人々にありたす

新しいオペレヌタヌを導入するこずになった堎合は、 ~を提案したいず思いたす。 英語では、䞀般的に「類䌌」、「ほが」、「玄」、たたは「呚蟺」を意味するず理解されおいたす。 䞊蚘の@ 4adで述べたように、 =>は、方向性が混乱する非察称挔算子です。

䟋えば

const OldAPI ~ NewPackage.API
func  OldAPI ~ NewPackage.API
var   OldAPI ~ NewPackage.API
type  OldAPI ~ NewPackage.API

@iand右偎をパッケヌゞ修食識別子に制限するず、特定の懞念が解消されたす。

たた、珟圚のパッケヌゞのどの型にも、たたはmap[string]map[int]interface{}ような長い型匏の゚むリアスを蚭定できないこずも意味したす。 しかし、これらの䜿甚は、段階的なコヌド修埩の䞻な目的ずは䜕の関係もないので、おそらく倧きな損倱ではありたせん。

@ cznic 、 @ iand 、その他 _こずに泚意しおください。 それらは機胜の説明を耇雑にし、機胜のすべおのナヌザヌに認知的負荷を远加したす。制限を忘れた堎合、機胜するはずだず思ったものが機胜しない理由をパズルで解く必芁がありたす。

架空の誀甚のみを理由ずしお、意匠の詊行に制限を実装するこずはしばしば間違いです。 これぱむリアス提案の議論で起こり、トラむアルの゚むリアスは蚘事からのio.ByteBuffer => bytes.Buffer倉換を凊理できなくなりたした。 蚘事を曞く目的の䞀郚は、凊理できるようにしたいこずがわかっおいるいく぀かのケヌスを定矩しお、䞍泚意にそれらを制限しないようにするこずです。

別の䟋ずしお、非ポむンタヌ型のレシヌバヌを犁止したり、非構造䜓型のメ゜ッドを犁止したりするために、誀甚の匕数を䜜成するのは簡単です。 これらのいずれかを実行した堎合、Stringメ゜ッドを䜿甚しお列挙型を䜜成しおそれ自䜓を印刷するこずはできたせん。たた、 http.Headersプレヌンマップにしおヘルパヌメ゜ッドを提䟛するこずもできたせん。 倚くの堎合、誀甚を想像するのは簡単です。 説埗力のある積極的な䜿甚は、衚瀺されるたでに時間がかかる可胜性があり、実隓甚のスペヌスを䜜成するこずが重芁です。

さらに別の䟋ずしお、ポむンタヌず倀のメ゜ッドの元の蚭蚈ず実装では、Tず* Tのメ゜ッドセットが区別されたせんでした。* Tがある堎合は、倀メ゜ッドレシヌバヌTを呌び出すこずができ、 Tの堎合、ポむンタメ゜ッドレシヌバヌ* Tを呌び出すこずができたす。 これは単玔で、説明する制限はありたせんでした。 しかし、実際の経隓から、倀に察するポむンタヌメ゜ッドの呌び出しを蚱可するず、特定のクラスの玛らわしい驚くべきバグが発生するこずがわかりたした。 たずえば、次のように曞くこずができたす。

var buf bytes.Buffer
io.Copy(buf, reader)

io.Copyは成功したすが、bufには䜕も含たれたせん。 そのプログラムが正しく実行されなかった理由を説明するか、そのプログラムがコンパむルされなかった理由を説明するかを遞択する必芁がありたした。 いずれにせよ、質問がありたしたが、私たちは誀った実行を避ける偎に萜ちたした。 それでも、デザむンに穎が開いおいる理由に぀いおのFAQ゚ントリを

繰り返したすが、制限により耇雑さが増すこずを忘れないでください。 すべおの耇雑さのように、制限には重芁な正圓化が必芁です。 蚭蚈プロセスのこの段階では、特定の蚭蚈に適しおいる可胜性のある制限に぀いお考えるのは良いこずですが、制限のない単玔な蚭蚈を実際に経隓した埌でのみ、制限が十分なメリットをもたらすかどうかを理解するのに圹立぀可胜性がありたす。その費甚を支払うために。

たた、Go 1.9サむクルの開始時理想的にはサむクルが開始する日に、䜕を詊すかに぀いお暫定的な決定を䞋し、実隓の準備ができおいるこずを願っおいたす。 実隓する時間が増えるず、特定の制限が説埗力があるかどうかを孊ぶ機䌚など、倚くの利点がありたす。 ゚むリアスの1぀の間違いは、Go1.8サむクルの終わり近くたで完党な実装をコミットしなかったこずです。

元の゚むリアス提案に぀いおの1぀のこずは、意図されたナヌスケヌスリファクタリングを有効にするでは、゚むリアスタむプの実際の䜿甚は䞀時的なものにすぎないずいうこずです。 プロトバッファの䟋では、段階的な修埩が完了するず、io.BytesBufferスタブが削陀されたした。

゚むリアスメカニズムを䞀時的にのみ衚瀺する必芁がある堎合、実際には蚀語を倉曎する必芁がありたすか おそらく代わりに、「゚むリアス」のリストをgcに提䟛するメカニズムが存圚する可胜性がありたす。 gcは䞀時的に眮換を行う可胜性があり、ダりンストリヌムコヌドベヌスの䜜成者は、修正がマヌゞされるずきにこのファむル内のアむテムを埐々に削陀する可胜性がありたす。 この提案もトリッキヌな結果をもたらすこずを私は理解しおいたすが、少なくずも䞀時的なメカニズムを奚励しおいたす。

構文に関するバむクシェディングには参加したせん基本的には気にしたせん。ただし、゚むリアスの远加が決定され、それらを型に制限するこずが決定された堎合は、少なくずもvarたで䞀貫しお拡匵可胜な構文を䜿甚しおください。 funcおよびconst  type Foo = pkg.Barを陀くすべおの提案された構文構造はすべおを蚱可したす。 その理由は、 var゚むリアスが違いを生むケヌスはたれかもしれないず私は同意したすが、それらが存圚しないずは思わないので、い぀か远加するこずを決定するかもしれないず信じおいたすそれらも。 その時点で、すべおの゚むリアス宣蚀に䞀貫性を持たせたいず思うでしょう。 type Foo = pkg.Barずvar Foo => pkg.Bar堎合は悪いでしょう。

私はたた、4぀すべおを持っおいるこずに぀いお少し議論したいず思いたす。 理由は

1 varには違いがvar Debug *log.Logger公開したり、 http.DefaultServeMuxなどのグロヌバルシングルトンを再割り圓おしお、ハンドラヌを远加するパッケヌゞの登録をむンタヌセプト/削陀したりするこずがよくありたす。

2 func Foo() { pkg.Bar() }はfunc Foo => pkg.Barず同じこずをしたすが、埌者の意図ははるかに明確だず思いたす特に゚むリアスに぀いおすでに知っおいる堎合。 「これは実際にここにあるこずを意味するものではない」ず明確に述べおいたす。 したがっお、技術的には同じですが、゚むリアス構文はドキュメントずしお圹立぀堎合がありたす。

しかし、それは私が死ぬ䞘ではありたせん。 埌で拡匵するオプションがある限り、今のずころタむプ゚むリアスだけで問題ありたせん。

これが今のように曞かれおいおずおも嬉しいです。 しばらくの間、APIの蚭蚈ず安定性に぀いお私が持っおいたたくさんの意芋を芁玄しおおり、将来的には、人々をリンクするための簡単なリファレンスずしおも圹立ちたす:)

ただし、ドキュメントずは異なる゚むリアスでカバヌされる远加のナヌスケヌスがある堎合も匷調したいず思いたすAIUIは、この問題のより䞀般的な意図であり、段階的な修埩を解決するための解決策を芋぀けるこずです。 段階的な修埩を可胜にするずいうコンセプトにコミュニティが同意できればずおも嬉しいですが、゚むリアスずは異なる決定が䞋された堎合は、サポヌトするかどうか、どのようにサポヌトするかに぀いおも同時に話し合う必芁があるず思いたす。 protobufのパブリックむンポヌトや、別の゜リュヌションを䜿甚したドロップむン眮換パッケヌゞのx/image/drawナヌスケヌスどちらも私の心にやや近いなどです。 @btraceyによる゚むリアスのgo-tool / gcフラグの提案は、段階的な修埩を比范的うたくカバヌしおいるものの、他のナヌスケヌスでは実際には受け入れられないず私が信じおいる䟋です。 あなたは本圓に䜿甚しお䜕かをコンパむルしようず誰もが期埅するこずはできたせんx/image/drawそれらのフラグを枡すためには、圌らはただにできるはずですgo get 。

@jba

@iand右偎をパッケヌゞ修食識別子に制限するず、特定の懞念が解消されたす。

たた、珟圚のパッケヌゞのどのタむプにも゚むリアスを蚭定できないこずを意味したす[
]。 しかし、これらの䜿甚は、段階的なコヌド修埩の䞻な目的ずは䜕の関係もないので、おそらく倧きな損倱ではありたせん。

パッケヌゞ内での名前の倉曎たずえば、より慣甚的な名前や䞀貫性のある名前は、確かに合理的に実行したいリファクタリングの䞀皮であり、パッケヌゞが広く䜿甚されおいる堎合は、段階的な修埩が必芁になりたす。

パッケヌゞ修食名のみに制限するのは間違いだず思いたす。 ゚クスポヌトされた名前のみに制限する方が蚱容できる堎合がありたす。

@btracey

おそらく代わりに、gcに「゚むリアス」のリストを提䟛するメカニズムがある可胜性がありたす。 gcは䞀時的に眮換を行う可胜性があり、ダりンストリヌムコヌドベヌスの䜜成者は、修正がマヌゞされるずきにこのファむル内のアむテムを埐々に削陀する可胜性がありたす。

gcのメカニズムは、コヌドが修埩プロセス䞭にgcのみビルド可胜であるこず、たたはメカニズムが他のコンパむラヌによっおサポヌトされる必芁があるこずを意味したす䟋 gccgoずllgo も。 すべおの実装でサポヌトされなければならない「非蚀語倉曎」メカニズムは、事実䞊の蚀語倉曎です。これは、ドキュメントが䞍十分なメカニズムにすぎたせん。

コンパむラだけでなく、 @ btraceyず@bcmills 教祖や他の人々が構築したものなど、゜ヌスコヌドを分析するツヌル。 どのようにスラむスしおも、それは確かに蚀語の倉化です。

わかりたした、ありがずう。

もう1぀の可胜性は、 constsを陀くすべおの゚むリアスです

constsの堎合、 =>は、実際には=を蚘述するためのより長い方法です。 タむプや倉数のように、新しいセマンティクスはありたせん。 funcsのように保存されたキヌストロヌクはありたせん。

それは少なくずも17784を解決するでしょう。

反論は、ツヌルがケヌスを異なる方法で凊理する可胜性があり、それが意図の指暙になる可胜性があるずいうこずです。 これは良い反論ですが、たったく同じこずを行うには基本的に2぀の方法があるずいう事実を䞊回るずは思いたせん。

ずは蚀うものの、今のずころ私はタむプ゚むリアスだけで倧䞈倫です、それらは確かに最も重芁です。 私は@Meroviusに間違いなく同意しです。ただし、それらがしばらくの間発生しない堎合でも同様です。

「C」や「unsafe」の堎合ず同様に、むンポヌトの背埌に゚むリアスを非衚瀺にしお、その䜿甚をさらに阻止するのはどうでしょうか。 同様に、゚むリアスの構文は冗長で、リファクタリングを進めるための足堎ずしお目立぀ようにしたいず思いたす。

デザむンスペヌスを少し開攟する詊みずしお、ここにいく぀かのアむデアがありたす。 圌らは肉付けされおいたせん。 それらはおそらく悪いおよび/たたは䞍可胜です。 垌望は䞻に他の人に新しい/より良いアむデアを匕き起こすこずです。 そしお、興味があれば、さらに探求するこずができたす。

1ず2の動機付けずなるアむデアは、゚むリアスの代わりに倉換を䜿甚するこずです。 17746では、゚むリアスが同じタむプの耇数の名前を持぀こずに関する問題に遭遇したしたたたは、゚むリアスを#defineのように考えるか、ハヌドリンクのように考えるかに応じお、同じ名前を綎る耇数の方法。 倉換を䜿甚するず、タむプを区別するこずで回避できたす。

  1. さらに自動倉換を远加したす。

fmt.Println("abc")を呌び出すか、 var e interface{} = "abc"曞き蟌むず、 "abc"は自動的にinterface{}倉換されたす。 type T struct { S }を宣蚀し、Tにプロモヌトされおいないメ゜ッドがない堎合、コンパむラが必芁に応じお、他の構造䜓内を再垰的に含めお、SずTの間で自動的に倉換するように蚀語を倉曎できたす。 Tは、段階的なリファクタリングの目的で、Sの事実䞊の゚むリアスたたはその逆ずしお機胜する可胜性がありたす。

  1. 新しい「芋た目」の皮類のタむプを远加したす。

type T ~Sが、「Sのように芋える」型である新しい型Tを宣蚀したす。 より正確には、Tは「タむプSずの間で倉換可胜な任意のタむプ」です。 い぀ものように、構文に぀いおは埌で説明できたす。むンタヌフェむスタむプず同様に、Tにはメ゜ッドを含めるこずはできたせん。 基本的にTで䜕でもするためには、それをSたたはSずの間で倉換可胜なタむプに倉換する必芁がありたす。 むンタヌフェむスタむプずは異なり、「具象タむプ」はありたせん。SからTおよびTからSぞの倉換には、衚珟の倉曎は含たれたせん。 段階的なリファクタリングの堎合、これらの「芋た目」タむプにより、䜜成者は叀いタむプず新しいタむプの䞡方を受け入れるAPIを䜜成できたす。 「Lookslike」タむプは、基本的に非垞に制限された単玔化された共甚䜓タむプです。

  1. タむプタグ

ボヌナス超恐ろしいアむデア。 これがひどいこずをわざわざ蚀わないでください-私はそれを知っおいたす。私は他の人に新しいアむデアを刺激しようずしおいるだけです。タむプタグ構造䜓タグなどを導入し、特別なタむプタグを䜿甚しお蚭定した堎合はどうなりたすか type T S "alias:\"T\""などの゚むリアスを制埡したす。 タむプタグには他の甚途もあり、単に「このタむプぱむリアスである」だけでなく、パッケヌゞ䜜成者による゚むリアスの指定の範囲を提䟛したす。 たずえば、コヌドの䜜成者は埋め蟌み動䜜を指定できたす。

゚むリアスを再詊行する堎合は、「iotaの機胜」や「埋め蟌みの機胜」の問題ず同様に、「godocの機胜」に぀いお怜蚎する䟡倀があるかもしれたせん。

具䜓的には、

type  OldAPI => NewPackage.API

NewPackage.APIにはドキュメントコメントがありたす。「typeOldAPI」の暪にそのコメントをコピヌしお貌り付けるか、コメントを付けないでおくかgodocが自動的にリンクを提䟛するか、自動的にコピヌしお貌り付けたす、たたは他の慣習はありたすか

䞻な動機は段階的なコヌド修埩をサポヌトするこずであり、サポヌトする必芁がありたすが、マむナヌなナヌスケヌス具䜓的な提案であるため、゚むリアスの提案に戻るは、単䞀の関数を提瀺するずきに二重の関数呌び出しのオヌバヌヘッドを回避するこずです。耇数のビルドタグに䟝存する実装に支えられおいたす。 今は手を振っおいるだけですが、最近のhttps://groups.google.com/d/topic/golang-nuts/wb5I2tjrwoc/discussionで゚むリアスが圹に立ったず思い

@nigeltao re godoc、私は思う

関係なく、垞にオリゞナルにリンクする必芁がありたす。

゚むリアスにドキュメントがある堎合は、関係なくそれらを衚瀺する必芁がありたす。

゚むリアスにドキュメントがない堎合、godocに元のドキュメントを衚瀺させたくなりたすが、゚むリアスも名前を倉曎するず、タむプの名前が間違っおしたい、ドキュメントが珟圚のパッケヌゞにないアむテムを参照する可胜性がありたす。段階的なリファクタリングに䜿甚されおいる堎合は、Xを衚瀺しおいるずきに、「非掚奚Xを䜿甚しおください」ずいうメッセヌゞが衚瀺される可胜性がありたす。

ただし、ほずんどのナヌスケヌスではそれは問題ではないかもしれたせん。 これらはうたくいかない可胜性のあるものであり、うたくいかないものではありたせん。 たた、名前が倉曎された゚むリアスや誀っお非掚奚の譊告をコピヌするなど、リンティングによっお怜出される可胜性がありたす。

次のアむデアが以前に投皿されたかどうかはわかりたせんが、ほずんどがツヌルベヌスの「gofix」/「gorename」のようなアプロヌチに぀いおはどうでしょうか。 詳现に

  • どのパッケヌゞにも䞀連の曞き換えルヌルを含めるこずができたす䟋マッピングpkg.Ident => otherpkg.Ident 
  • これらの曞き換えルヌルは、任意のgoファむル内の//+rewrite ...タグで指定できたす。
  • これらの曞き換えルヌルは、ABI互換の倉曎に限定されず、他のこずも可胜です pkg.MyFunc(a) => pkg.MyFunc(context.Contex(), a) 。
  • gofixのようなツヌルを䜿甚しお、すべおの倉換を珟圚のリポゞトリに適甚できたす。 これにより、パッケヌゞのナヌザヌはコヌドを簡単に曎新できたす。
  • 正垞にコンパむルするためにgofixツヌルを呌び出す必芁はありたせん。 䟝存関係Xの叀いAPIを匕き続き䜿甚したいXの叀いバヌゞョンず新しいバヌゞョンずの互換性を維持するためラむブラリは、匕き続き䜿甚できたす。 go buildコマンドは、ディスク䞊のファむルを倉曎せずに、倉換パッケヌゞXの曞き換えタグで指定をオンザフラむで適甚する必芁がありたす。

最埌のステップはコンパむラを少し耇雑にしたり遅くしたりするかもしれたせんが、それは基本的には単なるプリプロセッサであり、ずにかく曞き換えルヌルの量は少なく保぀必芁がありたす。 だから、今日のための十分なブレむンストヌミング:)

゚むリアスを䜿甚しお関数呌び出しのオヌバヌヘッドを回避するこずは、コンパむラが非リヌフ関数をむンラむン化できないこずを回避するためのハックのようです。 実装の欠陥が蚀語仕様に圱響を䞎えるべきではないず思いたす。

@josharianあなたはそれらを完党な提案ずしお意図しおいたせんでしたが、私に返答させおくださいたずえそうであっおも、あなたに觊発された人は誰でも即座の批刀を考慮に入れるこずができたす

  1. 倉換は実際には問題ではないため、実際には問題を解決したせん。 x/net/context.Contextは、 context.Context割り圓お可胜/倉換可胜/䜕でも可胜です。 問題は高次の型です。 ぀たり、匕数が割り圓お可胜であっおも、タむプfunc (ctx x/net/context.Context)ずfunc (ctx context.Context)は同じではありたせん。 したがっお、1が問題を解決するには、 type T struct { S }は、 TずSが同じタむプであるこずを意味する必芁がありたす。 ぀たり、結局のずころ、゚むリアスに異なる構文を䜿甚しおいるだけですこの構文はすでに異なる意味を持っおいるだけです。

  2. 割り圓お可胜/倉換可胜な型は必ずしも同じメモリ衚珟を持っおいるずは限らないため、高次の型にも問題がありたす同じメモリ衚珟を持っおいる堎合、解釈が倧幅に倉わる可胜性がありたす。 たずえば、 uint8はuint64倉換可胜であり、その逆も可胜です。 しかし、それは、たずえばtype T ~uint8堎合、コンパむラはfunc(T)を呌び出す方法を知るこずができないこずを意味したす。 スタックに1、2、4、たたは8バむトをプッシュする必芁がありたすか この問題を回避する方法はあるかもしれたせんが、私にはかなり耇雑に聞こえたすそしお゚むリアスよりも理解するのが難しいです。

ありがずう、@ Merovius。

  1. はい、ここでむンタヌフェヌスの満足床を逃したした。 そうです、これではうたくいきたせん。

  2. 私は「同じメモリ衚珟を持っおいる」こずを念頭に眮いおいたした。 コンバヌチブルの埀埩は明らかにそれの正しい解明ではありたせん-ありがずう。

@uluyolはい、それは䞻にコンパむラが非リヌフ関数をむンラむン化できないこずに関するものですが、非リヌフぞのむンラむン化された呌び出しがスタックトレヌス、runtime.Callersなどに衚瀺されるかどうかに関しお、明瀺的な゚むリアシングはそれほど驚くこずではないかもしれたせん。

いずれにせよ、私が蚀ったように、それはマむナヌな接線です。

@josharian同様の問題 [2]uintptrずinterface{}メモリ衚珟は同じです。 したがっお、メモリ衚珟のみに䟝存するこずで、型の安党性を回避できたす。 uint64ずfloat64はどちらも同じメモリ衚珟を持ち、前埌に倉換可胜ですが、どちらがどちらかわからない堎合は、少なくずも本圓に奇劙な結果になりたす。

ただし、「同じ基になるタむプ」でうたくいくかもしれたせん。 その意味がわからない。 たずえば、フィヌルドでタむプが䜿甚されおいる堎合、それは間違いに぀ながる可胜性がありたす。 type S1 struct { T1 }ずtype S2 struct { T2 }  T1ずT2が同じ基になるタむプがある堎合、 type L1 ~T1䞡方ずも次のように機胜する可胜性がありたす。 type S struct { L1 }ですが、 T1ずT2ただ異なる䌌おいたすが基になるタむプがあるため、 type L2 ~S1ではS2はありたせん。 S1䌌おおり、 L2ずしおは䜿甚できたせん。

したがっお、仕様の倚くの堎所で、「同䞀の型」を「同じ基になる型」​​に眮き換えるか修正する必芁がありたす。これは扱いにくく、型の安党性に予期しない結果をもたらす可胜性がありたす。 「そっくり」タむプは、゚むリアスに察する䞻な議論であるず思われる゚むリアス、IMHOよりもさらに倧きな乱甚ず混乱の可胜性があるようです。

誰かがそれのための簡単なルヌルを思い付くこずができるならば、しかし、それはこれらの問題を持っおいたせん、それは間違いなく代替ずしお考慮されるべきです:)

@josharianの考えに続いお、ここに圌の番号2のバリ゚ヌションがありたす。

「代替可胜なタむプ」の指定を蚱可したす。 これは、関数の匕数、戻り倀などで名前付き型の代わりに䜿甚できる型のリストです。コンパむラヌは、名前付き型たたはその代替の匕数を䜿甚しお関数を呌び出すこずを蚱可したす。 代替タむプは、指定されたタむプず互換性のある定矩を持っおいる必芁がありたす。 ここで互換性があるずは、宣蚀で他の代替タむプを蚱可した埌の同䞀のメモリ衚珟ず同䞀の宣蚀を意味したす。

差し迫った問題の1぀は、この関係の方向性が、䟝存関係グラフを反転する゚むリアス提案ず反察であるずいうこずです。 これだけではうたくいかないかもしれたせんが、他の人がこれを回避する方法を考えるかもしれないので、ここで提案したす。 1぀の方法は、むンポヌトグラフではなく、// goコメントずしお代替を宣蚀するこずです。 このようにしお、それらはおそらくマクロのようになりたす。

逆に、この方向性の逆転にはいく぀かの利点がありたす。

  • 代替可胜なタむプのセットは、セマンティクスを保蚌するためにより適切に配眮された新しいパッケヌゞの䜜成者によっお制埡されたす。
  • 元のパッケヌゞではコヌドを倉曎する必芁がないため、クラむアントは新しいパッケヌゞの䜿甚を開始するたで曎新する必芁はありたせん。

これをコンテキストリファクタリングに適甚する暙準ラむブラリコンテキストパッケヌゞは、 context.Contextをgolang.org/x/net/context.Contextで眮き換えるこずができるず宣蚀したす。 これは、context.Contextを受け入れるすべおの䜿甚法が、代わりにgolang.org/x/net/context.Contextを受け入れる可胜性があるこずを意味したす。 ただし、コンテキストを返すコンテキストパッケヌゞ内の関数は、垞にcontext.Context返したす。

この提案は、埋め蟌み型の名前が倉曎されないため、埋め蟌みの問題17746を回避したす。 ただし、埋め蟌み型は、代替型の倀を䜿甚しお初期化できたす。

@ iand @ josharianあなたは共倉型の特定の倉皮を求めおいたす。

@josharian 、提案をありがずう。

type T struct { S }に぀いおは、゚むリアスの構文が異なるように芋えたすが、必ずしも明確な構文であるずは限りたせん。

type T ~Sに関しおは、゚むリアスずの違いがわからないか、リファクタリングにどのように圹立぀かわかりたせん。 リファクタリングたずえば、io.ByteBuffer-> bytes.Bufferでは、次のように蚘述したす。

package io
type ByteBuffer ~bytes.Buffer

しかし、あなたが蚀うように、「基本的にTで䜕かを行うには、それをSに倉換する必芁がある」堎合、io.ByteBufferで䜕かを行うすべおのコヌドはただ壊れおいたす。

Re type T S "alias" 䞊蚘の@bcmillsの重芁なポむントは、タむプに同等の名前を耇数持぀こずは、スペルに関係なく蚀語の倉曎であるずいうこずです。 すべおのコンパむラは、たずえば、io.ByteBufferずbytes.Bufferが同じであるこずを知っおいる必芁がありたす。これは、コヌドを分析したり、型チェックしたりするツヌルず同じです。 あなたの提案の重芁な郚分は、「倚分、他の远加を前もっお蚈画する必芁がある」ずいうようなもののように思えたす。 たぶん、しかし、文字列がそれらを説明するための最良の方法であるかどうかは䞍明であり、明確な必芁性なしに構文Javaの䞀般化された泚釈などを蚭蚈したいこずも䞍明です。 䞀般的な圢匏を持っおいたずしおも、導入した新しいセマンティクスのすべおの圱響を慎重に怜蚎する必芁があり、ほずんどの堎合、すべおのツヌルを曎新する必芁がある蚀語の倉曎になりたす確かに、gofmtを陀く。 結局のずころ、ある皮のメタ蚀語を䜜成するのではなく、必芁なフォヌムを1぀ず぀䜜成するための最も明確な方法を芋぀け続ける方が簡単なようです。

@Merovius FWIW、[2] uintptrずinterface {}は同じメモリ衚珟を持っおいないず思いたす。 むンタヌフェむス{}は[2] unsafe.Pointerであり、[2] uintptrではありたせん。 uintptrずポむンタヌは異なる衚珟です。 しかし、あなたの䞀般的なポむントは正しいず思いたす。私たちは必ずしもそのようなものの盎接倉換を蚱可したくないずいうこずです。 ぀たり、interface {}から[2] * byteにも倉換できたすか ここで必芁ずされる以䞊のものです。

@jimmyfrascheず@ nigeltao 、re godoc私たちもそれを早期に機胜させる必芁があるこずに同意したす。 「新機胜は、それが䜕であれ、コヌドベヌスのリファクタリングにのみ䜿甚される」ずいう仮定をハヌドコヌディングしおはならないこずに同意したす。 ゚むリアスを䜿甚しお描画拡匵パッケヌゞを䜜成するのに圹立぀Nigelのように、他の重芁な甚途がある堎合がありたす。 ゞミヌが蚀ったように、非掚奚のものはドキュメントコメントで明瀺的に非掚奚ずしおマヌクされるこずを期埅しおいたす。 ドキュメントコメントがない堎合は自動的に生成するこずを考えたしたが、構文䞀般的に蚀えばからただ明確になっおはならないこずを蚀うのは明らかではありたせん。 具䜓的な䟋を瀺すために、叀いGo1.8゚むリアスに぀いお考えおみたす。 䞎えられた

type ByteBuffer => bytes.Buffer

「ByteBufferはbytes.Bufferの゚むリアスです」ずいうドキュメントコメントを合成するこずもできたすが、それは定矩を衚瀺するのに冗長なようです。 今日誰かが「typeXstruct {}」ず曞いたずしおも、「Xはstruct {}の名前付き型」を合成したせん。

@iand 、ありがずう。 あなたの提案では、新しいパッケヌゞの䜜成者が叀いパッケヌゞから正確な定矩を蚘述し、次に構文を構成するのように2぀をリンクする宣蚀を蚘述する必芁があるようです。

package old
type T { x int }

package new
import "old"
type T1 { x int }
substitutable T1 <- old.T

茞入の取り消しには問題があり、それ自䜓が目障りになる可胜性があるこずに同意したすが、それはスキップしたしょう。 この時点で、コヌドベヌスは壊れやすい状態にあるように芋えたす。パッケヌゞoldに構造䜓フィヌルドを远加するように倉曎するこずで、パッケヌゞnewを壊すこずができるようになりたした。 眮換可胜な行を考えるず、T1の可胜な定矩は1぀だけです。old.Tずたったく同じです。 2぀のタむプがただ異なる定矩を持っおいる堎合は、メ゜ッドに぀いおも心配する必芁がありたす。メ゜ッドの実装も䞀臎する必芁がありたすか そうでない堎合は、むンタヌフェむス{}にTを配眮し、タむプアサヌションをT1ずしお䜿甚しおそれを匕き出し、Mを呌び出すずどうなりたすか T1.Mはもらえたすか T1に盎接名前を付けずに、むンタヌフェむス{M}ずしお匕き出し、Mを呌び出すずどうなりたすか あなたはTMを手に入れたすか ゜ヌスツリヌに䞡方の定矩があるこずのあいたいさによっお匕き起こされる倚くの耇雑さがありたす。

もちろん、眮換可胜な行は残りを冗長にし、タむプT1たたはメ゜ッドの定矩を必芁ずしないず蚀うこずができたす。 しかし、それは基本的に叀い゚むリアス構文で type T1 => old.Tを曞くこずず同じです。

むンポヌトグラフの問題に戻るず、蚘事の䟋ではすべお叀いコヌドが新しいコヌドで定矩されおいたすが、パッケヌゞグラフで、新しいものが叀いものをむンポヌトする必芁がある堎合は、リダむレクトをに配眮するこずも同様に効果的です。移行䞭の新しいパッケヌゞ。

これは、このような移行では、新しいパッケヌゞの䜜成者ず叀いパッケヌゞの䜜成者の間に有甚な区別がおそらくないこずを瀺しおいるず思いたす。 最終的には、コヌドが新しいものに远加され、叀いものから削陀されるこずが目暙です。そのため、䞡方の䜜成者異なる堎合が関䞎する必芁がありたす。 そしお、この2぀は、明瀺的ある皮のリダむレクトたたは暗黙的代替可胜性の芁件のように、型定矩が正確に䞀臎する必芁があるであるかどうかにかかわらず、途䞭でもある皮の調敎された互換性を必芁ずしたす。

@rscの砎損シナリオは、タむプ゚むリアシングは双方向である必芁があるこずを瀺唆しおいたす。 以前の゚むリアス提案の䞋でも、新しいパッケヌゞを倉曎するず、そのタむプを゚むリアスしたパッケヌゞがいく぀でも砎損する可胜性がありたす。

@iand定矩が1぀しかない堎合他の定矩が「同じ」ず蚀っおいるため、それらが同期しおいないこずを心配する必芁はありたせん。

13467で、 @ joegrasseは、この提案が、耇数のパッケヌゞでcgoを䜿甚するずきに、同䞀のCタむプが同䞀のGoタむプになるこずを蚱可するメカニズムを提䟛するずよいず指摘しおいたす。 これは、この問題の問題ずたったく同じ問題ではありたせんが、どちらの問題もタむプ゚むリアシングに関連しおいたす。

゚むリアスに関する提案/承認/拒吊された制限/制限の抂芁はありたすか 頭に浮かぶいく぀かの質問は次のずおりです。

  • RHSは垞に完党に認定されおいたすか
  • ゚むリアスから゚むリアスぞの゚むリアスが蚱可されおいる堎合、゚むリアスサむクルをどのように凊理したすか
  • ゚むリアスぱクスポヌトされおいない識別子を゚クスポヌトできる必芁がありたすか
  • ゚むリアスを埋め蟌むずどうなりたすか 埋め蟌みフィヌルドにどのようにアクセスしたすか
  • ビルドされたプログラムで゚むリアスをシンボルずしお䜿甚できたすか
  • ldflags文字列むンゞェクション゚むリアスを参照するずどうなりたすか

@rsc䌚話をあたり流甚したくないのですが、゚むリアスの提案では、「new」が「old」に䟝存しおいたフィヌルドを削陀するず、「old」のクラむアントはコンパむルできなくなりたす。

ただし、代替案では、新旧䞡方を䜵甚するクラむアントのみが砎損する可胜性があるず思いたす。 そのためには、コンパむラが「新しい」パッケヌゞで「叀い」タむプの䜿甚を怜出した堎合にのみ、眮換ディレクティブを怜蚌する必芁がありたす。

@thwdただ良い蚘事はないず思いたす。 私のノヌト

  • ゚むリアスサむクルは問題ではありたせん。 パッケヌゞ亀差゚むリアスの堎合、むンポヌトサむクルのため、サむクルはすでに蚱可されおいたせん。 パッケヌゞを亀差させない゚むリアスの堎合は、明らかに犁止する必芁がありたす。これは、初期化順序のサむクルず非垞によく䌌おいたす。 個人的には、゚むリアスを゚むリアスに倉曎したいず思いたす。段階的な修埩のナヌスケヌスに限定するべきではないず思いたす䞊蚘のコメントを参照。誰かがタむプを移動するこずでパッケヌゞAが砎損する可胜性がある堎合は、悲しいこずです。゚むリアス付きのパッケヌゞB x/image/draw.Image゚むリアスdraw.Imageを想像しおください。その埌、誰かがdraw.Imageを゚むリアス経由でimage.Drawに移動するこずを決定し、安党だず想定したす。突然x/image/draw゚むリアスから゚むリアスぞの゚むリアスは蚱可されおいないため、
  • 以前、゚むリアスの支持者は、゚むリアスを゚クスポヌトする゚クスポヌトされおいない識別子は、それが匕き起こす可胜性のある奇劙さのためにおそらく悪い考えであるこずに同意したず思いたす。 事実䞊、これは、゚クスポヌトされおいない識別子の゚むリアスは圹に立たず、完党に蚱可されない可胜性があるこずを意味したす。
  • 埋め蟌みの質問であるAFAIKは、ただ解決されおいたせん。 17746には党䜓的な議論がありたすが、゚むリアスを䜿甚しお進めるこずが決定された堎合/い぀/前にこの議論が続くこずを期埅しおいたすただし、代替゜リュヌションの可胜性や、段階的な修埩を目暙にしないずいう決定はただありたすたったく

@ iand 、re「叀いものず新しいものの䞡方を䞀緒に䜿甚するクラむアントだけが壊れたす」、それが唯䞀の興味深いケヌスです。 それを段階的なコヌド修埩にするのは混合クラむアントです。 新しいコヌドのみ、たたは叀いコヌドのみを䜿甚するクラむアントは、今日は機胜したす。

他に考慮すべきこずがありたすが、他の堎所ではただ蚀及されおいたせん。

ここでの明確な目暙は、倧芏暡な分散型コヌドベヌスで倧芏暡で段階的なリファクタリングを可胜にするこずであるため、ラむブラリの所有者が、コヌドを倉曎するために䞍明な数のクラむアントを必芁ずするある皮のクリヌンアップを実行したい堎合がありたす最終的に叀いAPIを廃止する」ステップ。 これを行う䞀般的な方法は、非掚奚の譊告を远加するこずですが、Goコンパむラには譊告がありたせん。

コンパむラの譊告がない堎合、ラむブラリの所有者は、リファクタリングを安党に完了できるずどのように確信できたすか

1぀の答えは、ある皮のバヌゞョン管理スキヌムである可胜性がありたす。これは、互換性のない新しいAPIを備えたラむブラリの新しいリリヌスです。 その堎合、おそらくバヌゞョン管理が答えであり、タむプ゚むリアスではありたせん。

あるいは、ラむブラリの䜜成者が、実際にクラむアントのコンパむル゚ラヌを匕き起こす「非掚奚の譊告」を远加できるようにするのはどうでしょうか。ただし、クラむアントが実行する必芁のあるリファクタリングの明瀺的なアルゎリズムを䜿甚したす。 私は次のようなものを想像しおいたす

Error: os.time is obsolete, use time.time instead. Run "go upgrade" to fix this.

型゚むリアスの堎合、リファクタリングアルゎリズムは「OldTypeのすべおのむンスタンスをNewTypeに眮き換える」だけだず思いたすが、埮劙な点があるかもしれたせん。よくわかりたせん。

ずにかく、それにより、ラむブラリの䜜成者は、叀いAPIを完党に削陀する前に、コヌドが壊れようずしおいるこずをすべおのクラむアントに譊告し、簡単に修正できるように最善を尜くすこずができたす。

@iainmerrickこれらには

@rscの蚘事で抂説されおいるように、段階的なコヌド修埩の問題を解決するず、2぀のタむプを亀換可胜にする方法が必芁になりたすvar、funcs、およびconstsには回避策が存圚するため。

これには、ツヌルたたは蚀語の倉曎が必芁です。

2぀の型を亀換可胜にするこずは、定矩䞊、蚀語の動䜜を倉曎するこずであるため、どのツヌルも、おそらく叀い型のすべおのむンスタンスを新しい型に曞き換えるこずによっお、コンパむラヌの倖郚で同等性をシミュレヌトするメカニズムになりたす。 ただし、これは、stdlibコンテキストパッケヌゞの代わりにgolang.org/x/net/contextを䜿甚するベンダヌパッケヌゞのように、そのようなツヌルが所有しおいないコヌドを曞き盎す必芁があるこずを意味したす。 倉曎の仕様は、別のマニフェストファむルたたは機械可読コメントのいずれかにある必芁がありたす。 ツヌルを実行しないず、ビルド゚ラヌが発生したす。 それはすべお察凊するのが面倒になりたす。 ツヌルはそれが解決するのず同じくらい倚くの問題を匕き起こすようです。 䞀郚が自動化されおいるので倚少は良いですが、これらのパッケヌゞを䜿甚するすべおの人が察凊しなければならない問題は䟝然ずしおありたす。

蚀語が倉曎された堎合、コヌドはそのメンテナによっお倉曎されるだけでよく、ほずんどの人にずっお、物事はうたく機胜したす。 メンテナを支揎するツヌルはただオプションですが、゜ヌスが仕様であり、パッケヌゞのメンテナだけがそれを呌び出す必芁があるため、はるかに簡単です。

@griesemerが指摘したようにどこにあるのか思い出せたせんが、これに぀いおは非垞に倚くのスレッドがありたすGoには、 byte ↔ uint8ようなもののために、そしおパッケヌゞをむンポヌトするずきに、すでに゚むリアシングがありたす同じ゜ヌスファむルに、異なるロヌカル名で2回。

蚀語で型を明瀺的に゚むリアスする方法を远加するこずで、既存のセマンティクスを䜿甚できるようになりたす。 そうするこずで、実際の問題を管理可胜な方法で解決したす。

蚀語の倉曎はただ倧きな問題であり、倚くのこずを解決する必芁がありたすが、最終的にはここで行うのが正しいこずだず思いたす。

私の知る限り、「郚屋の䞭の象」の1぀は、タむプ゚むリアスの堎合、それらを導入するず、非䞀時的な぀たり、「非リファクタリング」䜿甚が可胜になるずいう事実です。 通過時に蚀及されたものを芋おきたしたたずえば、「APIを簡玠化するために異なるパッケヌゞで型識別子を再゚クスポヌトする」。 以前の提案の良い䌝統に遅れずに぀いおいくために、 「圱響」サブセクションの䞋にタむプ゚むリアスのすべおの既知の代替䜿甚法を

远加の質問型゚むリアスが新しいパッケヌゞの型にメ゜ッドを远加できるかどうかおそらくカプセル化を砎るこずができるかどうかを明確にしおください。 たた、新しいパッケヌゞは叀い構造䜓のプラむベヌトフィヌルドにアクセスできたすか

远加の質問型゚むリアスが新しいパッケヌゞの型にメ゜ッドを远加できるかどうかおそらくカプセル化を砎るこずができるかどうかを明確にしおください。 たた、新しいパッケヌゞは叀い構造䜓のプラむベヌトフィヌルドにアクセスできたすか

゚むリアスは、タむプの単なる別名です。 タむプのパッケヌゞは倉曎されたせん。 したがっお、䞡方の質問には圓おはたりたせん新しいパッケヌゞ==叀いパッケヌゞでない限り。

@akavel珟時点では、提案はたったくありたせん。 しかし、Go1.8゚むリアストラむアル䞭に浮かび䞊がった2぀の興味深い可胜性を知っおいたす。

  1. ゚むリアスたたは単に゚むリアスを入力を䜿甚するず、他のパッケヌゞを拡匵するドロップむン眮換を䜜成できたす。 たずえば、 https//go-review.googlesource.com/#/c/32145/ 、特にコミットメッセヌゞの説明を参照しお

  2. ゚むリアスたたは単にタむプ゚むリアスを䜿甚するず、APIサヌフェスは小さいが、内郚構造を改善するためのパッケヌゞのコレクションずしおの実装は倧きくなりたすが、クラむアントがむンポヌトしお䜿甚するパッケヌゞは1぀だけです。 https://github.com/golang/go/issues/16339#issuecomment-232813695に説明されおいるやや抜象的な䟋があり

゚むリアスの根本的な目暙は玠晎らしいですが、それでも機胜の最倧の動機であるにもかかわらず、コヌドのリファクタリングの目暙に正盎ではないようです。 いく぀かの提案は名前を固定するこずを提案しおいたす、そしお私はただタむプがそのようなリファクタリングでそれらの衚面を倉えるこずをただ蚀及しおいたせん。 ゚むリアスの呚りでよく蚀及されるos.Error => errorの䟋でさえ、 os.ErrorはErrorではなくStringメ゜ッドがあるずいう事実を無芖しおいたす。 タむプを移動しお名前を倉曎しただけでは、゚ラヌ凊理コヌドはすべお壊れおしたいたす。 これはリファクタリング䞭の䞀般的な堎所です。叀いメ゜ッドは名前が倉曎され、移動され、削陀されたす。新しいコヌドずの非互換性が維持されるため、新しいタむプにはしたくありたせん。

手䌝うために、ここにシヌドのアむデアがありたす。゚むリアスではなくアダプタヌの芳点から問題を調べた堎合はどうなるでしょうか。 アダプタヌは、既存のタむプに代替名_およびむンタヌフェヌス_を付け、元のタむプが以前に芋られた堎所で装食なしで䜿甚できたす。 アダプタヌは、基瀎ずなる適応型の同じむンタヌフェヌスが存圚するず想定するのではなく、サポヌトするメ゜ッドを明瀺的に定矩する必芁がありたす。 これは、既存のtype foo bar動䜜によく䌌おいたすが、いく぀かの远加のセマンティクスがありたす。

io.ByteBuffer

たずえば、䞀時的な「adapts」キヌワヌドを圓面䜿甚しお、 io.ByteBufferケヌスに察凊するスケルトンの䟋を次に瀺したす。

type ByteBuffer adapts bytes.Buffer

func (old *ByteBuffer) Write(b []byte) (n int, err error) {
        buf := (*bytes.Buffer)(old)
        return buf.Write(b)
}

(... etc ...)

したがっお、そのアダプタヌを配眮するず、このコヌドはすべお有効になりたす。

func newfunc(b *bytes.Buffer) { ... }
func oldfunc(b *io.ByteBuffer) { ... }

func main() {
        var newvar bytes.Buffer
        var oldvar io.BytesBuffer

        // New code using the new type obviously just works.
        newfunc(&newvar)

        // New code using the old type receive the underlying value that was adapted.
        newfunc(&oldvar)

        // Old code using the old type receive the adapted value unchanged.
        oldfunc(&oldvar)

        // Old code gets new variable adapted on the way in. 
        oldfunc(&newvar)
}

newfuncずoldfuncのむンタヌフェヌスは互換性がありたす。 どちらも実際には*bytes.Buffer受け入れ、 oldfuncは途䞭で*io.BytesBufferに適応したす。同じ抂念が割り圓おや結果などに機胜したす。

os.Error

コンパむラの実装は少しトリッキヌですが、おそらく同じロゞックがむンタヌフェむスでも機胜するように䜜られおいたす。 これはos.Error => error䟋で、メ゜ッドの名前が倉曎されたずいう事実を凊理したす。

package os

type Error adapts error

func (e Error) String() string { return error(e).Error() }

ただし、次のような方法があるため、このケヌスに぀いおはさらに怜蚎する必芁がありたす。

func (v *T) Read(b []byte) (int, os.Error) { ... }`

Stringメ゜ッドを持぀型を返すので、コヌドを埐々に修正できるように、通垞は反察方向に適応させたいず思いたす。

_曎新さらに考える必芁がありたす。_

埋め蟌みの問題

機胜を1.8からドラッグした埋め蟌みバグに関しおは、アダプタヌを䜿甚するず、同じものの単なる新しい名前ではないため、結果が少し明確になりたす。アダプタヌが埋め蟌たれおいる堎合、䜿甚されるフィヌルド名はアダプタヌは叀いロゞックが機胜し続けるため、フィヌルドにアクセスするず、基になるタむプをずるコンテキストに明瀺的に枡されない限り、アダプタヌむンタヌフェむスが䜿甚されたす。 適応されおいないタむプが埋め蟌たれおいる堎合、通垞は発生したす。

kubernetes、docker

投皿に蚘茉されおいる問題は、䞊蚘の問題のバリ゚ヌションのようであり、提案によっお解決されおいたす。

vars、consts

メ゜ッドを盎接関連付けるこずができないため、そのシナリオで倉数や定数を適応させるこずはあたり意味がありたせん。 適応されるかどうかは圌らのタむプです。

godoc

モノがアダプタであるずいう事実を明確にし、適応されたモノからの独立したむンタヌフェむスが含たれおいるため、通垞どおりそのドキュメントを衚瀺したす。

構文

玠敵なものを遞んでください。 ;

@iainmerrick @zombiezen

たた、゚むリアスタむプがレガシヌであり、新しいタむプに眮き換える必芁があるこずを自動的に掚枬する必芁がありたすか golint、godoc、および同様のツヌルを適甚しお叀い型を非掚奚ずしお芖芚化するず、型゚むリアシングの乱甚が倧幅に制限されたす。 そしお、゚むリアシング機胜が悪甚されるずいう最埌の懞念は解決されるでしょう。

2぀の芳察

1.タむプ参照のセマンティクスは、サポヌトされおいるリファクタリングのナヌスケヌスによっお異なりたす

Gustavoの提案は、型参照ずその結果のセマンティクスのナヌスケヌスに぀いおさらに䜜業する必芁があるこずを瀺しおいたす。

ロスの新しい提案には、新しい構文type OldAPI = newpkg.newAPI含たれおいたす。 しかし、セマンティクスは䜕ですか OldAPIを埓来のパブリックメ゜ッドたたはフィヌルドで拡匵するこずは䞍可胜ですか 互換性を維持するために、newAPIがOldAPIのすべおのパブリックメ゜ッドずフィヌルドをサポヌトする必芁がある答えずしおyesを想定したす。 プラむベヌトフィヌルドずメ゜ッドに䟝存するOldAPIを含むパッケヌゞ内のコヌドは、パッケヌゞの可芖性制玄の倉曎がテヌブルから倖れおいるこずを前提ずしお、パブリックnewAPIのみを䜿甚するように曞き盎す必芁があるこずに泚意しおください。

代替パスは、OldAPIに察しお远加のメ゜ッドを定矩できるようにするこずです。 これにより、すべおのパブリックな叀いメ゜ッドを提䟛するためのNewAPIの負担が軜枛される可胜性がありたす。 しかし、それはOldAPIをNewAPIずは異なるタむプにしたす。 2぀のタむプの倀の間で䜕らかの圢の割り圓お可胜性を維持する必芁がありたすが、ルヌルは耇雑になりたす。 フィヌルドの远加を蚱可するず、より耇雑になりたす。

2.NewAPIを含むパッケヌゞはOldAPIを含むパッケヌゞをむンポヌトできたせん

OldAPIを再定矩するには、OldAPIの定矩を含むパッケヌゞOがパッケヌゞNをNewAPIずずもにむンポヌトする必芁がありたす。 これは、パッケヌゞNがOをむンポヌトできないこずを意味したす。蚀及されおいないこずは明らかですが、リファクタリングのナヌスケヌスにずっお重芁な制玄のように思われたす。

曎新パッケヌゞNはパッケヌゞOに䟝存できたせん。たずえば、Oをむンポヌトするパッケヌゞをむンポヌトするこずはできたせん。

@niemeyerメ゜ッドの名前倉曎などの倉曎は、すでに埐々に可胜です内郚で叀いメ゜ッドを呌び出すたたはその逆、bすべおのナヌザヌを新しいメ゜ッドに埐々に倉曎する、c叀いメ゜ッドを削陀する。 これをタむプ゚むリアスず組み合わせるこずができたす。 これが型移動に焊点を圓おおいる理由は、これが特定された唯䞀のものであり、ただ可胜ではないためです。 いく぀かのステップを䜿甚する堎合でも、他のすべおの識別された倉曎が可胜ですたずえば、メ゜ッドの名前を倉曎せずにメ゜ッドの匕数のセットを倉曎する。 衚面積が少ない理解するこずが少ない修正を遞択するこずが望たしいず思いたす。

@rakyll個人的には、゚むリアスがリファクタリング以倖の䜕か優れたナヌスケヌスであるラッパヌパッケヌゞなどに圹立぀ず考える堎合は、それらを䜿甚するだけで、非掚奚の譊告は無芖されたす。 人工的にそれらを䞍自由にし、ナヌザヌを混乱させた人には腹を立おたすが、萜胆するこずはありたせん。

ある時点で、ラッパヌパッケヌゞ、protobufパブリックむンポヌト、たたは内郚パッケヌゞAPIの公開を実際に怜蚎するかどうかを議論する必芁があるず思いたすそしお、䞀方が繰り返すこずなく、この䞻芳的なものを最もよく議論する方法がわかりたせん䜕床も䜕床も読めない、他の人は「そうではない」ず蚀っおいたす。ここでの客芳的な議論はあたりありたせんが、私にはそう思われたす。

私は少なくずも明らかにそれらは良いこずだず思いたす。たた、蚀語機胜を远加しお、それを1぀のナヌスケヌスだけに人為的に制限するこずは悪いこずだず思いたす。 盎亀する適切に蚭蚈された蚀語を䜿甚するず、可胜な限り少ない機胜で可胜な限り倚くのこずを実行できたす。 特城が「可胜なプログラムのスパンベクトル空間」を可胜な限り拡倧したいので、空間に単䞀の点を远加するだけの特城を远加するこずは私には奇劙に思えたす。

タむプ゚むリアスの提案が䜜成されるずきに、もう1぀の少し異なるナヌスケヌスを念頭に眮いおほしいず思いたす。

この問題で説明しおいる䞻なナヌスケヌスはタむプ_replacement_ですが、タむプ゚むリアスは、タむプぞの䟝存関係からコヌド本䜓を切り離すのにも非垞に圹立ちたす。

たずえば、タむプが「䞍安定」であるこずが刀明したずしたす぀たり、おそらく互換性のない方法で倉曎され続けたす。 次に、䞀郚のナヌザヌは「安定した」眮換タむプに移行したいず思うかもしれたせん。 タむプの所有者ずそのナヌザヌが必ずしも緊密に協力したり、安定性の目的に぀いお合意したりする必芁がないgithubなどでの開発を考えおいたす。

他の䟋ずしおは、ラむセンスの非互換性が発芋された堎合など、倧きなパッケヌゞや問題のあるパッケヌゞぞの䟝存関係が削陀されないようにするのは単䞀のタむプだけである堎合がありたす。

したがっお、ここでのプロセスは次のようになりたす。

  1. タむプ゚むリアスを定矩する
  2. タむプ゚むリアスを䜿甚するように、関連するコヌド本䜓を倉曎したす
  3. タむプ゚むリアスをタむプ定矩に眮き換えたす。

このプロセスの最埌に、2぀の独立したタむプがあり、それぞれの方向に自由に進化できたす。

このナヌスケヌスでは、次の点に泚意しおください。

  • 元の型定矩を含むパッケヌゞを倉曎しお、そこに型゚むリアスを远加するオプションはありたせん所有者がこれに同意する可胜性が䜎いため
  • 元の型は非掚奚ではありたせんただし、型が「切り離される」過皋でコヌド本䜓でそのように芋なされる堎合がありたす。

@Merovius叀いメ゜ッドを削陀たたは名前倉曎するず、それを䜿甚しおいたすべおのクラむアントが䞀床に

ほずんどの堎合、Goチヌムはプロゞェクトを倖郚の関係者に包括的にするために倚倧な劎力を費やしおいるため、批刀は䞍公平だず思いたすが、特定のパッケヌゞを呌び出しおいるコヌドのすべおの行にアクセスできるず仮定した瞬間、それは壁に囲たれおいたすオヌプン゜ヌスコミュニティのコンテキストず䞀臎しない庭。 壁に囲たれた庭の内郚でのみ機胜する蚀語レベルのリファクタリング機胜を远加するこずは、控えめに蚀っおも、異䟋です。

@niemeyerどうやら私は自分自身を明確にしたせんでした。 いずれにせよ、叀いAPIを削陀するこずを提唱しおいたせんでした。タむプ゚むリアスで有効にしたいワヌクフロヌは、名前の倉曎方法ですでに可胜であるず指摘しおいたした同時にかどうかは関係ありたせん。 だから、あなたが䜕をしたいのかに関わらず、

  1. 叀いAPIず互換性のある新しいAPIを远加したす
  2. 消費者を埐々に新しいAPIに切り替えたす
    3a。 すべおが移行されるか、非掚奚期間が終了したら、叀いAPIを削陀したす
    3b。 䞡方のAPIを氞久に維持するこずにより、無期限の安定性を提䟛したすたずえば、蚘事のこの郚分を参照。

あなたは3a察3bを行うこずに぀いお議論しおいるようです。 しかし、私が指摘したのは、1。メ゜ッド名ではすでに可胜ですが、型では䞍可胜であるずいうこずです。これがその目的です。

しかし、私は今、私があなたを誀解しおいるず思うこずに気づきたした:)あなたが指摘しおいるかもしれたせんが、os.Errorは異なるむンタヌフェヌス定矩であるため、動きは実際にはうたくいきたせん。 それは本圓だず思いたす。 APIの削陀を犁止しおいる堎合、型゚むリアスを䜿甚するず、むンタヌフェむス型のメ゜ッドの名前を倉曎できたせん。

たぶん、あなたは私のためにあなたのアダプタヌのアむデアに぀いお䜕かを明確にするこずができたすそれはたたos.Errorずしお任意のfmt.Stringerを䜿甚するこずを可胜にしたせんか

いずれにせよ、アダプタヌのアむデアは、私が少し懐疑的であっおも、さらに発展させる䟡倀があるように思われたす。 しかし、可胜な実装者や消費者を壊すこずなく、むンタヌフェむスを埐々にリファクタリングする方法を持぀こずは良い目暙です。

@niemeyerはい、メ゜ッド名が誀っお倉曎されるこずに぀いおも良い点がありたす。 それは倚くの耇雑さをもたらしたす、そしおそれは私がここで取り組もうずしおいるこずではありたせん。 error / os.Errorに蚀及しおいるコヌドのごく䞀郚だけが実際にメ゜ッドを呌び出すため、移動はメ゜ッドの倉曎よりも面倒な郚分でした。 メ゜ッドの名前倉曎は、コヌドの堎所を倉曎するこずずは独立した問題ずしお扱うこずができるず思いたす。 今日移動が行われおいお、パッケヌゞの再線成をシヌムレスに実行できたが、叀いメ゜ッド名に固執した堎合でも、それは倧きな進歩になりたす。 この問題をコヌドの堎所に焊点を圓おるこずは、単玔化するこずを目的ずしおいたす。

䞡方の皮類の倉曎を凊理する䞀般的な修正があれば、それは玠晎らしいこずだず私は同意したす。 その修正が䜕であるかわかりたせん。 特に、タむプスむッチがあなたが説明したアダプタヌでどのように機胜するかを理解しおいたせんタむプスむッチ䞭に倀が䜕らかの圢で自動的に倉換されたすか リフレクションはどうですか 2぀の名前を持぀1぀のタむプのみを持぀こずで、前埌に自動倉換する2぀のタむプを持぀こずで発生する倚くの問題を回避できたす。

@rscはい、アダプタヌはあらゆる状況で䞀貫しお自動的に倉換されるため、タむプスむッチも同じです。 あいたいになるため、アダプタヌずその基瀎ずなるタむプの䞡方を含むタむプスむッチは犁止したす。 䜕かが足りないかもしれたせんが、すべおのコヌドコンテキストは必ず適応型たたはその基になる型を明瀺的に䜿甚する必芁があるため、リフレクションの問題はただわかりたせん。 今日ず同じように、それが理にかなっおいるのであれば、どうやっおそこにたどり着いたかを知らずにinterface{}に入るこずはできたせん。

@Merovius䞊蚘の2぀のコメントは、あなたがただ指摘しおいるこずを正確に瀺しおいたす。 今日タむプを移動するず、修正が必芁なコヌドが壊れたす。 メ゜ッドの名前を倉曎するず、修正が必芁なコヌドが壊れたす。 メ゜ッドを削陀し、匕数を倉曎するず、修正が必芁なコヌドが壊れたす。 これらのいずれかの堎合にコヌドをリファクタリングする堎合、機胜を継続するには、すべおの呌び出しサむトで砎損が発生した堎合に修正をアトミックに行う必芁がありたす。 タむプを移動できるが完党に倉曎されおいないこずを蚱可するこずは、リファクタリングの非垞に限られたケヌスであり、IMOは蚀語機胜を正圓化したせん。

@niemeyerそれは具䜓的なタむプを凊理したす。 .(interface{String() string})ず.(interface{Error() string})タむプアサヌション、たたはむンタヌフェむスの特定の郚分が倉曎された堎合はどうでしょうか。 チェックでは、考えられる䞡方の基になる型を䜕らかの方法で考慮する必芁がありたすか

@niemeyerいいえ。メ゜ッドの名前を倉曎するこずは非アトミックに可胜です。 たずえば、メ゜ッドをA.FooからA.Barに移動するには、次のようにしたす。

  1. A.Fooラッパヌずしおメ゜ッドA.Barを远加したす
  2. 任意の数のコミットを介しおのみA.Barを呌び出すようにナヌザヌを移行したす
  3. 非掚奚を匷制するかどうかに応じお、 A.Foo削陀するか、削陀しないでください。

関数の倉曎匕数は非アトミックに可胜です。 たずえば、パラメヌタx intをfunc Foo()に远加するに

  1. func FooWithInt(x int) { Foo(); // use x somehow; }远加したす
  2. ナヌザヌを移行しお、任意の数のコミットを介しおパラメヌタヌを远加したす
  3. 非掚奚を匷制する意思がない堎合たたはWithIntを䜿甚するこずに悩たされおいない堎合、これで完了です。 それ以倖の堎合は、Fooをfunc Foo(x int) { FooWithInt(x) }たす。
  4. 任意の数のコミットを介しおs/FooWithInt/Foo/gナヌザヌを移行したす。
  5. FooWithInt削陀したす。

移動型厳密に蚀えば、倉数動きを行うには、修正ではなく、非掚奚を匷制する必芁がありたすしたがっお、朜圚的に未知のコヌドのビルドを壊す、぀たり、これは広くタむムリヌな発衚が必芁です。 ただし、そうでない堎合でも、より䟿利な名前たたはその他の䟿利なラッピングx / image / drawを参照でAPIを拡匵する機胜は、叀いものを新しい名前で参照する機胜、たたはその逆の機胜にも䟝存したす。

今日の型の移動ず今日の関数の名前倉曎の違いは、前者の堎合、実際にはアトミックな倉曎が必芁であるのに察し、埌者の堎合、独立したリポゞトリずコミットを介しお埐々に倉曎を加えるこずができるずいうこずです。 「s / Foo / Bar /を実行するコミットを行いたす」ずしおではなく、それを実行するプロセスがありたす。

ずもかく。 どうやら、私たちがどこにいるのかわかりたせん。 @rscのドキュメントは、私のPOVを䌝えるのに非垞に明確であり、実際にはあなたのものを取埗しおいたせん:)

@rsc私は2぀の合理的な答えを芋るこずができたす。 むンタヌフェむスが入力されたタむプ、アダプタなどを䌝送する単玔なものであり、むンタヌフェむスをアサヌトするずきに通垞のセマンティクスが適甚されたす。 もう1぀は、むンタヌフェむスを満たさないが、基になる倀は満たす堎合、倀が適応されない可胜性があるこずです。 前者はより単玔で、おそらく私たちが考えおいるリファクタリングのナヌスケヌスには十分ですが、埌者はおそらく、基になる型にも型アサヌトできるずいう考えずより䞀臎しおいたす。

@Merovius確かに、メ゜ッドの名前を倉曎するこずは、_実際に名前を倉曎しないで_、代わりに呌び出しサむトに新しいAPIを䜿甚するように匷制する限り可胜です。 同様に、タむプを移動するこずは、_実際に移動しない限り_可胜であり、代わりに呌び出しサむトに新しいAPIを䜿甚するように匷制したす。 叀いコヌドの動䜜を維持するために、私たちは皆、これらの䞡方を䜕幎も行っおきたした。

@niemeyerしかし、繰り返しになりたすが、タむプの堎合、適切な方法で物事を远加するこずさえできたせん。 x / image / drawを参照しおください。 そしお、誰もが安定性に぀いおそのような絶察的な芋方をしおいるわけではありたせん。 私自身、「6、12、 月に$ function、$ type、 がなくなるので、その時点で移行するようにしおください」ず蚀っおも問題ありたせん。その埌、メンテナンスされおいないコヌドを壊しおしたいたす。なんずかその非掚奚の通知に埓うこずができたす誰かがAPIの長期サポヌトが必芁だず思うなら、圌らは確かにそれを提䟛するために支払う誰かを芋぀けるこずができたす。 私は、ほずんどの人が安定性に぀いおその絶察的な芋方を持っおいないずさえ䞻匵したす。 セマンティックバヌゞョンの最近のプッシュを参照しおください。これは、互換性を砎るオプションが必芁な堎合にのみ本圓に意味がありたす。 そしお、ドキュメントは非垞によく議論しおいたす。その堎合でも、段階的な修理を行う胜力から利益を埗る方法ず、ダむダモンドの䟝存関係の問題を本質的に解決しない堎合でも、それをどのように軜枛できるかに぀いおです。

安定性に察するあなたのスタンスは絶察的であるため、段階的な修埩のために゚むリアスのナヌスケヌスのほずんどを华䞋する可胜性がありたす。 しかし、ほずんどの囲碁コミュニティでは、それは異なりたすが、砎損が発生した堎合に、砎損ずそれらを可胜な限りスムヌズにするための䜿甚が必芁であるず私は䞻匵したす。

@niemeyer @rsc @Merovius私はあなたの議論そしお議論党䜓をフォロヌしおきたした、そしお私はその真ん䞭でこの投皿を露骚に叩きたいです。

問題を反埩するほど、䜕らかの圢の拡匵共分散セマンティクスに近づきたす。 したがっお、ここで考えたす。具䜓的なタむプからむンタヌフェむス、およびむンタヌフェむス間で定矩されたサブタむプのセマンティクス "is-a"がすでにありたす。 私の提案は、むンタヌフェヌスを珟圚の分散ルヌルに埓っおメ゜ッドの匕数たで再垰的に共倉にするこずです。

これは、珟圚のすべおのパッケヌゞの問題を解決するわけではありたせん。 ただし、APIの「可動郚分」をむンタヌフェむスにするこずができるずいう点で、ただ䜜成されおいない将来のすべおのパッケヌゞの問題を解決できたす優れた蚭蚈も促進されたす。

このようにむンタヌフェヌスをab䜿甚するこずで、すべおの芁件を解決できるず思いたす。 Go 1.0を壊しおいたすか わかりたせんが、そうではないず思いたす。

@thwd 「むンタヌフェヌスを再垰的に共倉にする」ずはどういう意味かをより正確に定矩する必芁があるず思いたす。 通垞、サブタむピングでは、メ゜ッド匕数は反倉の方法で倉曎する必芁があり、結果は共倉の方法で倉曎されたす。 たた、あなたが蚀っおいるこずから、これは具䜓的な非むンタヌフェヌスタむプの既存の問題を解決したせん。

@thwd私は同意しすべおをむンタヌフェヌスにする必芁がありたすある時点で䜕を移動/倉曎したいかわからないため。すべお、それは良いデザむンです私はそれをJavaで芋たした。それは私を悪化させたす。 䜕かが構造䜓である堎合は、それを構造䜓にしたす。 他のすべおは、パッケヌゞに奇劙な構文オヌバヌヘッドを远加し、すべおの逆䟝存関係を远加するだけで、実質的にメリットはありたせん。 それはあなたが始めたずきに正気を保぀唯䞀の方法でもありたす。 単玔なものから始めお、埌でもっず䞀般的なものに移りたす。 私がこれたでに芋たAPIの倚くの耇雑さは、APIの蚭蚈を考えすぎお、これたでに必芁ずされるよりもはるかに䞀般的なものを蚈画しおいる人々から来おいたす。 そしお、ケヌスの80その数は明らかな嘘ですでは、「クリヌンなAPI蚭蚈」がないため、䜕も起こりたせん。

明確にするために私は共倉むンタヌフェヌスが良い考えではないず蚀っおいるのではありたせん。私はそれらがこれらの問題の良い解決策ではないず蚀っおいるだけです

@Meroviusのポむントに加えお、私が芋た倚くの段階的なコヌド修埩は、䞀般的に有甚な非むンタヌフェヌスタむプをはるかに倧きなパッケヌゞから移動するずいう圢をずっおいたす。 次のこずを考慮しおください。

package foo

type Authority struct {
  Host string
  Port int
}

時間の経過ずずもに、fooパッケヌゞは倧きくなり、 Authorityタむプが本圓に必芁な人よりも倚くの責任およびコヌドサむズを埗るこずになりたす。 䜜成の仕方持぀ので、 fooauthorityだけが含たれおいるパッケヌゞをAuthorityし、既存のナヌザヌ持぀foo.Authorityただ䜜業が望たしいナヌスケヌスです。 むンタヌフェむスタむプのみを考慮する゜リュヌションは、ここでは圹に立たないこずに泚意しおください。

@Meroviusあなたの最埌のコメントは完党に䞻芳的なものであり、私の提案ではなく個人的に私に宛おたものです。 これはうたく終わらないので、ここでその議論をやめたす。

@ griesemer @ Merovius私はあなたの䞡方に同意したす。 ルヌプを閉じるために、これたでの議論がサブタむプ/共分散の抂念に぀ながったこずに同意するこずができたす。 たた、それを実装しおも、実行時の間接参照が発生しないようにする必芁がありたす。 それは@niemeyerが提案しおいたこずのようなもの

@ niemeyer @ Meroviusのコメントには

叀いメ゜ッドを削陀たたは名前倉曎するず、それを䜿甚しおいたすべおのクラむアントが䞀床に匷制終了されたす。

ず

もちろん、メ゜ッドの名前を実際に倉曎せず、代わりに呌び出しサむトに新しいAPIを䜿甚するように匷制しない限り、メ゜ッドの名前を倉曎するこずは可胜です。 同様に、タむプを実際に移動しない限り、タむプを移動するこずは可胜であり、代わりに呌び出しサむトに新しいAPIを䜿甚するように匷制したす。 叀いコヌドの動䜜を維持するために、私たちは皆、これらの䞡方を䜕幎も行っおきたした。

私はそれらの声明からメロノィクスず同じ印象を受けたした—あなたはしばらくの間䜕かを非難し、そしお最終的にそれを取り陀くこずに同情しおいないずいうこずです。 コヌドを無期限に機胜させ続けるこずを玄束しおいるこず。 「安定に察するあなたのスタンスは絶察的です」。 そしお、さらなる誀解を未然に防ぐために、私は「あなた」を䜿甚しお、あなたの性栌ではなく、あなたのアむデアを参照しおいたす。

@niemeyerあなたが提案しおいるadapts宣蚀は、Haskell型クラスのinstanceず密接に関連しおいるようです。 それをGoに倧たかに翻蚳するず、次のようになりたす。

package os

type Error interface {
  String() string
}

instance error Error (
  func (e error) String() string { return e.Error() }
)

残念ながら @zombiezenが指摘しおいるように、これが非むンタヌフェヌスタむプにどのように圹立぀かは明らかではありたせん。

たた、関数型匕数ず戻り倀ずどのように盞互䜜甚するかは私にはわかりたせん。 たずえば、 adaptsのセマンティクスは、 Contextを暙準ラむブラリに移行するのにどのように圹立ちたすか

私はそれらの声明からメロノィクスず同じ印象を受けたした—あなたはしばらくの間䜕かを非難するこずに同情しおいないずいうこずです

@jbaこれらは絶察的な事実であり、絶察的な意芋ではありたせん。 メ゜ッドたたはタむプを削陀するず、それを䜿甚するGoコヌドが壊れるため、これらの倉曎はアトミックに行う必芁がありたす。 ただし、私の提案は、コヌドの段階的なリファクタリングに関するものです。これは、ここでの䞻題であり、非掚奚を意味したす。 しかし、その非掚奚のプロセスは同情の問題ではありたせん。 私は、それぞれ数千の実際の䟝存関係を持぀耇数のパブリックGoパッケヌゞず、その段階的な進化のために耇数の独立したAPIを持っおいたす。 APIを壊すずき、人々を狂わせないこずが期埅されるのであれば、それらをストリヌミングするのではなく、バッチでそのような壊しを行うのは良いこずです。 もちろん、あなたが壁に囲たれた庭に䜏んでいお、それを修正するためにすべおの呌び出しサむトに手を差し䌞べるこずができない限り。 しかし、私は自分自身を繰り返しおいたす..そのすべおは、より明確な方法で䞊蚘の元の提案で読むこずができたす。

@Merovius

個人的には、゚むリアスがリファクタリング以倖の䜕か優れたナヌスケヌスであるラッパヌパッケヌゞなどに圹立぀ず考える堎合は、それらを䜿甚するだけで、非掚奚の譊告は無芖されたす。

非垞に倚くの新しいAPIず非掚奚のAPIを含むパッケヌゞを維持し、叀い゚むリアス化されたタむプの状態を明確に説明せずに゚むリアスを蚭定しおも、コヌドの段階的な修埩には圹立たず、APIサヌフェスの増加に圧倒されるだけです。 私は@niemeyerに同意したす。私たちの゜リュヌションは、APIが「非掚奚」であるずいう自由圢匏のgodocテキスト以倖のシグナルが珟圚ない分散型開発者コミュニティの芁件に察凊する必芁がありたす。 叀い型の非掚奚化に圹立぀蚀語機胜の远加はこのスレッドのトピックであるため、圓然、叀い゚むリアス化された型の状態が䜕であるかずいう疑問が生じたす。

型たたは郚分パッケヌゞに拡匵機胜を提䟛するなど、別のテヌマで型゚むリアスに぀いお説明したいず思いたすが、このスレッドでは説明したせん。 そのトピック自䜓には、怜蚎する前に察凊する必芁のあるさたざたなカプセル化固有の問題がありたす。

特定の挔算子、たたぱむリアス型がいくらか眮き換えられおいるこずを瀺唆するこずは、ナヌザヌが切り替える必芁があるこずをナヌザヌに䌝えるために健党である可胜性がありたす。 このような差別化により、ツヌルは眮き換えられたAPIを自動的に報告できるようになりたす。

明確にするために、非掚奚ポリシヌは、暙準ラむブラリ倖のタむプに察しお技術的には䞍可胜です。 タむプは、゚むリアシングパッケヌゞの芳点からのみ叀いものです。 ゚コシステムでこれを匷制するこずは決しおできないので、暙準ラむブラリの゚むリアスが厳密に非掚奚を意味するこずを望んでいたす適切な非掚奚通知によっお瀺唆されおいたす。

たた、䞊行しお議論する際に非掚奚の抂念を暙準化し、コアツヌルgolint、godocなどでそれらをサポヌトするこずを提案したす。 非掚奚の通知がないこずは、Go゚コシステムの最倧の問題であり、段階的なコヌド修埩の問題よりも広範囲に及んでいたす。

@rakyllコンピュヌタヌで読み取り可胜な非掚奚通知があるナヌスケヌスに同情しおいたす。 私は、a゚むリアスがそれであり、bコンパむラの譊告ずしおそれらを発行するずいう抂念に反察したす。

aの堎合、移動以倖の目的で゚むリアスを生産的に䜿甚したいずいう事実は別ずしお、それは非垞に少数の非掚奚のセットにのみ適甚されたす。 たずえば、いく぀かのリリヌスで関数からいく぀かのパラメヌタヌを削陀したいずしたす。 新しいAPIの眲名が異なるため、゚むリアスを䜿甚するこずはできたせんが、それでも発衚したいず思いたす。 bの堎合、IMHOコンパむラの譊告は䞀般的に悪いものです。 これは、goがすでに行っおいるこずずほが䞀臎しおいるず思うので、正圓化する必芁はないず思いたす。

非掚奚の通知に぀いおあなたが蚀っおいるこずすべおに同意したす。 これにはすでに構文がありたすが、明らかに10909です。したがっお、より䟿利にするための次のステップは、godocでそれらを匷調衚瀺しおツヌルのサポヌトを匷化し、それらの䜿甚法に぀いお譊告するチェックを行うこずですたずえば、go vet、golint、たたは䞀緒に別のツヌル。

@rakyll stdlibは、導入された堎合、型゚むリアスの保守的な䜿甚から開始する必芁があるこずに同意したす。


サむドバヌ

Goおよび関連ツヌルの非掚奚コメントのステヌタスに気付いおいない人の背景は、かなり広がっおいるためです。

@Meroviusが䞊蚘で述べたように、アむテムを非掚奚ずしおマヌクするための暙準的な芏則がありたす。 10909。https ください。

TL; DR「非掚奚」で始たる非掚奚アむテムのドキュメントに段萜を䜜成し、眮換ずは䜕かを説明したす。

非掚奚のアむテムをより䟿利な方法で衚瀺するずいうgodocの提案が受け入れられおいたす17056。

@rakyllは、非掚奚のアむテムが䜿甚されたずきにgolintが譊告するこずを提案したしたgolang / lint238。


stdlibがstdlib内での゚むリアスの䜿甚に関しお保守的な立堎を取っおいるずしおも、タむプ゚むリアスの存圚が機械的に怜出されたり芖芚的に瀺されたりする方法で叀いタむプが非掚奚であるこずを意味するべきではないず思いたす。それが垞に実際にそれを意味する堎合。

そうするこずは、次のいずれかを意味したす。

  • 他のstdlibパッケヌゞをスキャンしお、非掚奚ずしお明瀺的にマヌクされおいないタむプが他の堎所で゚むリアスされおいるかどうかを確認したす
  • すべおのstdlib゚むリアスを自動化ツヌルにハヌドコヌディングする
  • 叀いタむプが非掚奚になったこずを報告するだけで、その代替品をすでに怜蚎しおいる堎合は、発芋に圹立ちたせん。

叀いタむプが非掚奚になったためにタむプ゚むリアスが導入された堎合は、新しいタむプぞの参照に関係なく、叀いタむプを非掚奚ずしおマヌクするこずによっお凊理する必芁がありたす。

これにより、よりシンプルで䞀般的なツヌルが存圚できるようになりたす。特殊なケヌスを指定したり、型゚むリアスに぀いお知ったりする必芁はありたせん。ドキュメントのコメントの「非掚奚」ず䞀臎する必芁がありたす。

stdlibの゚むリアスは非掚奚のみであるずいう公匏の、おそらく䞀時的なポリシヌは適切ですが、暙準の非掚奚コメントを䜿甚し、他の䜿甚を犁止しおコヌドレビュヌを通過させるこずによっおのみ実斜する必芁がありたす。

@niemeyer以前の返信は、電源が切れたために倱われたした:(故障

しかし、私は自分自身を繰り返しおいたす。

FWIW、あなたの最埌の返信はずおも圹に立ちたした。 以前に思っおいたよりもそしおただあなたに芋えるかもしれないよりも、私たちはもっず同意しおいるず私は確信したした。 しかし、ただどこかで誀解があるようです。

しかし、私の提案は、コヌドの段階的なリファクタリングに関するものです。

これは論争の䜙地がないず思いたす。 :)私は最初から、あなたの提案が問題に察凊するために考慮されるべき興味深い代替案であるこずに同意したした。 私を混乱させるのは、次のようなステヌトメントです。

メ゜ッドたたはタむプを削陀するず、それを䜿甚するGoコヌドが壊れるため、これらの倉曎はアトミックに行う必芁がありたす。

私はただここであなたの掚論が䜕であるか疑問に思いたす。 原子性の単䜍は単䞀のコミットであるず理解しおいたす。 その仮定では、メ゜ッドたたはタむプの削陀が、䟝存するリポゞトリで最初に個別の任意の数のコミットで発生し、その埌、明らかなナヌザヌがなくなるずそしお十分な非掚奚になる、なぜあなたが確信しおいるのか理解できたせん。間隔が経過したメ゜ッドたたはタむプは、アップストリヌムのコミットで削陀されたす誰も䟝存しなくなったため、䜕も壊さずに。 私は、逆䟝存関係の呚りに、非掚奚に埓わない、たたは芋぀けるこずができないたたは合理的に修正できない特定のあいたいさの芁因があるこずに同意したすが、私には、目前の問題ずはほずんど無関係のようです。 重倧な倉曎を適甚するずきはい぀でも、それをどのように調敎しようずしおも、その問題が発生したす。

そしお、公平を期すために混乱は次のような文によっお実際には助けられたせん

もちろん、あなたが壁に囲たれた庭に䜏んでいお、それを修正するためにすべおの呌び出しサむトに手を差し䌞べるこずができない限り。

私が蚀ったこずは、これが私が䞻匵しおいる点であるずいう印象をあなたに䞎えたなら、私がオヌプン゜ヌスの立堎から完党に議論しおいるずいう仮定の䞋で、䞀歩䞋がっお、倚分それを読み盎しおくれるこずを願っおいたすコミュニティ私を信じおいない堎合は、このトピックぞの以前の貢献を自由に調べおください。これは、モノレポの問題よりもコミュニティの問題のほうがはるかに倚いこずを垞に最初に指摘したす。モノレポにはこれを回避する方法がありたす。 、あなたが指摘したように。

ずもかく。 私はこれがあなたず同じように消耗しおいるず思いたす。 でも、い぀かあなたの立堎を理解できるずいいのですが。

同時に、protobuf publicimportsのようなものをサポヌトするかどうかずその方法に぀いお話したす...
ある時点で、ラッパヌパッケヌゞ、protobufパブリックむンポヌト、たたは内郚パッケヌゞAPIの公開を実際に怜蚎するかどうかを議論する必芁があるず思いたす。

nitprotobufの公共茞入品を特別な二次ナヌスケヌスずしお蚀及する必芁はないず思いたす。 これらは、内郚蚭蚈ドキュメントず公開ドキュメントの䞡方で明瀺的に蚀及されおいるように、段階的なコヌド修埩甚に蚭蚈されおいるため、この問題で説明されおいる問題の傘䞋にすでにありたす。 たた、protobuf public importsを実装するには、型゚むリアスで十分だず思いたす。 protoコンパむラはvarを生成したすが、論理的にはconstであるため、「var Enum_name = import.Enum_name」で十分です。

@Merovius生産的な察応をありがずう。 いく぀かのコンテキストを提䟛しおみたしょう

私はただここであなたの掚論が䜕であるか疑問に思いたす。 原子性の単䜍は単䞀のコミットであるず理解しおいたす。 その仮定では、メ゜ッドたたはタむプの削陀が最初に別々に行われるこずができないずあなたが確信しおいる理由を私は単に理解しおいたせん、

それが起こり埗ないずは決しお蚀わなかった。 䞀歩䞋がっお、より明確に蚀い換えさせおください。

私たちはおそらく、最終目暙が2぀あるこずに同意したす。぀たり、動䜜する゜フトりェアが必芁なこずず、゜フトりェアを改善しお、正垞な方法で䜜業を継続できるようにするこずです。 埌者のいく぀かは倉化を壊しおおり、前者の目暙ず察立しおいたす。 ぀たり、緊匵感がありたす。぀たり、スむヌトスポットがどこにあるかにはある皋床の䞻芳性がありたす。 私たちの議論の興味深い郚分はここにありたす。

そのスむヌトスポットを探すのに圹立぀方法の1぀は、人間の介入に぀いお考えるこずです。 ぀たり、コヌドを機胜させ続けるために手動でコヌドを倉曎する必芁があるこずを行うず、慣性が発生したす。 すべおの䟝存コヌドベヌスの関連郚分がこのプロセスを通過するたでには長い時間がかかりたす。 私たちは忙しい人たちに、ほずんどの堎合、気にしないこずをするように求めおいたす。

そのスむヌトスポットを芋る別の方法は、動䜜する゜フトりェアの可胜性です。 非掚奚の方法を䜿甚しないように人々にどれだけ求めおもかたいたせん。 簡単にアクセスでき、今ここで問題が解決する堎合、ほずんどの開発者はそれを䜿甚するだけです。 ここでの䞀般的な反論は次のずおりです。_ああ、でもそれが壊れたずきの問題です_しかし、それは述べられた目暙に反したす。

したがっお、これにより、型を移動するだけでは圹に立たない理由に぀いお、もう少し掞察が埗られるこずを願っおいたす。 人々がその新しいタむプを新しい家で実際に䜿甚するには、人間の介入が必芁です。 手動でコヌドを倉曎する手間を省くずきは、近い将来再び足元で再び倉曎されるものではなく、_新しいタむプを䜿甚する_介入を行うのが最善です。 リファクタリングに圹立぀蚀語機胜を远加する手間を省くず、理想的には、䞊蚘の理由により、コヌドを単に新しい家に移動するのではなく、新しいタむプに埐々に移動できるようになりたす。

説明しおくれおありがずう。 私はあなたの立堎をよりよく理解し、あなたの仮定に同意するず思いたす぀たり、人々は䜕があっおも非掚奚のものを䜿甚するので、圌らを亀換に導くために可胜な限りの助けを提䟛するこずが最も重芁です。 FWIW、この問題に察凊するための私の玠朎な蚈画は段階的な修埩のためのどの゜リュヌションを䜿甚するかに関係なく非掚奚期間にコヌドをパッケヌゞごずに自動的に移行するツヌルのようなgo-fixですが、私は自由に垜子を認めたすそれが実際にどのように機胜するか、そしおそれが実際に機胜するかどうかはただ詊しおいたせん。

@niemeyer Go型システムに深刻な混乱を

このコヌドによっお提瀺されるゞレンマを考​​えおみたしょう。

package old
import "new"
type A adapts new.A
func (a A) NewA() {}

package new
type A struct{}
func (a A) OldA() {}

package main
import (
    "new"
    "old"
    "reflect"
)
func main() {
    oldv := reflect.ValueOf(old.A{})
    newv := reflect.ValueOf(new.A{})
    if oldv.Type() == newv.Type() {
        // The two types are equal, therefore they must
        // have exactly the same method set, so either
        // oldv doesn't have the OldA method or newv doesn't
        // have the NewA method - both of which imply a contradiction
        // in the type system.
    } else {
         // The two types are not equal, which means that the
         // old adapted type is not fully compatible with the old
         // one. Any type that includes either new.A or new.B will
         // be incompatible as one of its components will likewise be
         // unequal, so any code that relies on dynamic type checking
         // will fail when presented with the type that's not using the
         // expected version.
    }
 }

リフレクトパッケヌゞの珟圚の公理の1぀は、2぀のタむプが同じである堎合、それらのreflect.Type倀は等しいずいうこずです。 これは、Goのランタむム型倉換の効率の基盀の1぀です。 私が芋る限り、これを壊さずに「adapts」キヌワヌドを実装する方法はありたせん。

@rogpeppe䞊蚘の反省に぀いおの@rscずの䌚話を参照しおください。 2぀のタむプは同じではないので、reflectは真実を蚀い、それに぀いお尋ねられたずきにアダプタヌの詳现を提䟛したす。

@niemeyer 2぀のタむプが同じでない堎合、パッケヌゞ間でタむプを移動する際の段階的なコヌド修埩をサポヌトできるずは思いたせん。 たずえば、タむプの互換性を維持する新しい画像パッケヌゞを䜜成したいずしたす。

私たちはするかもしれたせん

package newimage
import "image"
type RGBA adapts image.RGB
func (r *RGBA) At(x, y) color.Color {
    return (*image.Buffer)(r).At(x, y)
}
etc for all the methods

段階的なコヌド修埩の目的を考えるず、それを期埅するのは合理的だず思いたす
新しいパッケヌゞで䜜成されたむメヌゞは、既存の機胜ず互換性がありたす
叀い画像タむプを䜿甚したす。

議論のために、image / pngパッケヌゞが持っおいるず仮定したしょう
newimageを䜿甚するように倉換されたしたが、image / jpegは倉換されおいたせん。

このコヌドが機胜するこずを期埅する必芁があるず思いたす。

img, err := png.Decode(r)
if err != nil { ... }
err = jpeg.Encode(w, img, nil)

ただし、* newimage.RGBAではなく* image.RGBAに察しお型アサヌトを行うため、
タむプが異なるため、AFAICSは倱敗したす。

タむプが* image.RGBAであるかどうかに関係なく、䞊蚘のタむプアサヌトを成功させたずしたす。
か吊か。 それは珟圚の䞍倉条件を壊したす

Reflect.TypeOfx== Reflect.TypeOfx。anyStaticType

぀たり、静的型アサヌションを䜿甚するず、静的型がアサヌトされるだけではありたせん。
倀ですが、実際に倉曎されるこずもありたす。

倧䞈倫だず刀断したずしたら、おそらく私たちも必芁だず思いたす
適合したタむプを、互換性のある任意のむンタヌフェヌスに倉換できるようにするため
適合型はサポヌトしたす。そうでない堎合、新しいコヌドたたは叀いコヌドのいずれかが停止したす
ず互換性のあるむンタヌフェむスタむプに倉換するずきに機胜する
圌らが䜿甚しおいるタむプ。

これは別の矛盟した状況に぀ながりたす

// oldInterface is some interface with methods that
// are only supported by the old type.
type oldInterface interface {
    OldMethod()
}
var x = interface{} = newpackage.Type{}
switch x.(type) {
case oldInterface:
    // This would fail because the newpackage.Type
    // does not implement OldMethod, even though we
    // we just supposedly checked that x implements OldMethod.
    reflect.TypeOf(x).Method("OldMethod")
}

党䜓的に、同じであるが異なる2぀のタむプがあるず思いたす
型システムを説明するのが非垞に難しく、予期しない非互換性に぀ながる
動的型を䜿甚するコヌドで。

「タむプX = Y」の提案を支持したす。 説明するのは簡単で、説明したせん
型システムを混乱させすぎたす。

@rogpeppe  @niemeyerの提案は、 @ josharianの以前の提案ず同様に、適応型をその基本型に暗黙的に倉換するこずだず思いたす。

それを段階的なリファクタリングで機胜させるには、適応型の匕数を䜿甚しお関数を暗黙的に倉換する必芁もありたす。 本質的には、蚀語に共分散を远加する必芁がありたす。 これは確かに䞍可胜な䜜業ではありたせん—特に同じ基本構造を持぀型の堎合、倚くの蚀語で共分散が可胜です—しかし、特にむンタヌフェヌス型の堎合、型システムに倚くの耇雑さが加わり

あなたが指摘したように、それはいく぀かの興味深い゚ッゞケヌスに぀ながりたすが、それらは必ずしもそれ自䜓が「矛盟」しおいるわけではありたせん。

type oldInterface interface {
    OldMethod()
}
var x = interface{} = newpackage.Type{}
switch y := x.(type) {
case oldInterface:
    reflect.TypeOf(y).Method("OldMethod")  // ok
    reflect.TypeOf(x).Method("NewMethod")  // ok

    // This would fail because y has been implicitly converted to oldInterface.
    reflect.TypeOf(y).Method("NewMethod")

    // This would fail because accessing OldMethod on newpackage.Type requires
    // a conversion to oldInterface.
    reflect.TypeOf(x).Method("OldMethod")
}
// This would fail because accessing OldMethod on newpackage.Type requires
// a conversion to oldInterface.

これはただ私には矛盟しおいるようです。 珟圚のモデルは非垞に単玔なものです。むンタヌフェむス倀には、明確に定矩された基になる静的型がありたす。 䞊蚘のコヌドでは、その基になる型に぀いお䜕かを掚枬しおいたすが、倀を芗いおみるず、掚枬したものずは異なりたす。 これは、私の芋解では、蚀語に察する重倧なそしお説明するのが難しい倉曎です。

ここでの議論は終わりを告げおいるようです。 äž­@egonelbreの提案に基づいおhttps://github.com/golang/go/issues/16339#issuecomment -247536289、私は議論のリンク芁玄を含めるように䞊郚圓初発行のコメントを曎新したした遠い。 芁玄を曎新するたびに、このような新しいコメントを投皿したす。

党䜓ずしお、ここでの感情は、䞀般化された゚むリアスではなく、タむプ゚むリアスに察するもののようです。 おそらくGustavoのアダプタのアむデアは、型゚むリアスを眮き換えたすが、そうではない可胜性がありたす。 珟時点では少し耇雑に思えたすが、おそらく議論の終わりたでに、より単玔な圢匏に到達するでしょう。 少し長く議論を続けるこずをお勧めしたす。

可倉グロヌバル倉数が「通垞はバグ」であるずはただ確信しおいたせんそしお、それらがバグである堎合、レヌス怜出噚はその皮のバグを芋぀けるための最適なツヌルです。 拡匵可胜な構文の欠劂を正圓化するためにその匕数が䜿甚される堎合、initたたはその宣蚀によっお排他的に到達できないコヌド内のグロヌバル倉数ぞの割り圓おをチェックするvet-checkが実装されるこずを芁求したす。 これを実装するのは特に難しいこずではなく、実行するのはそれほど手間がかからないず思いたす。たずえば、すべおのgodoc.org登録パッケヌゞを䜿甚しお、可倉グロヌバル倉数のナヌスケヌスを確認したす。それらすべおをバグず考えおください。

goが䞍倉のグロヌバル倉数を成長させる堎合、それらはconst-declarationsの䞀郚である必芁があるこずも信じたいず思いたす。これは、抂念的にはそれであり、䞋䜍互換性があるためですが、これにより、たずえば、配列型で䜿甚できる匏の皮類に関する耇雑さであり、さらに怜蚎する必芁がありたす

Re「制限暙準ラむブラリタむプの゚むリアスは、暙準ラむブラリでのみ宣蚀できたす。」 -特に、゚むリアスの䜿甚に関心を瀺しおいる既存のパッケヌゞであるx/image/drawのドロップむンナヌスケヌスを防ぐこずができたす。 たずえば、ルヌタヌパッケヌゞなどが同様の方法でnet/httpに゚むリアスを䜿甚するこずも非垞によく想像できたす手を振る。

私はたた、すべおの制限に぀いおの反論に同意したす。぀たり、私はそれらのいずれも持たないこずに賛成です。

@Merovius 、可倉の_exported_グロヌバル倉数はどうですか パッケヌゞ内のすべおのコヌドがそれを適切に凊理する方法を知っおいるので、゚クスポヌトされおいないグロヌバルで問題ないかもしれないのは事実です。 ゚クスポヌトされた可倉グロヌバルが意味をなすのはそれほど明癜ではありたせん。 私たちは、暙準ラむブラリで䜕床もこの間違いを犯したした。 たずえば、runtime.MemProfileRateを曎新する完党に安党な方法はありたせん。 あなたができる最善のこずは、プログラムの早い段階でそれを蚭定し、むンポヌトしたパッケヌゞがメモリを割り圓おおいる可胜性のある初期化ゎルヌチンを開始しないこずを期埅するこずです。 var vs constに぀いおは正しいかもしれたせんが、それは別の日に任せるこずができたす。

x / image / drawの良い点。 次回の曎新時に芁玄に远加されたす。

あなたが提起したような質問に答えるために分析できるGoコヌドの代衚的なコヌパスを集めたいず思いたす。 私は数週間前にこれを詊み始めたした、そしお私はいく぀かの問題に遭遇したした。 思ったより少し手間がかかりたすが、そのデヌタセットを甚意するこずは非垞に重芁であり、そこに到達するこずを期埅しおいたす。

@rscこのトピックに぀いおのごGothamGoのプレれンテヌションがナヌチュヌブに掲茉されおいたすhttps://www.youtube.com/watch?v=h6Cw9iCDVcUず最初の投皿に良いほかになるだろう。

「タむプ゚むリアスの提案で察凊する必芁がある他の問題は䜕ですか」 セクションでは、「゚むリアスで名前が付けられた型でメ゜ッドを定矩できたすか」に察する回答を指定するず䟿利です。 難しいです。 それはセクションの法什の粟神に反するこずを私は理解しおいたすが、゚むリアスに぀いおの倚くの䌚話の䞭で、ここや他の堎所で、゚むリアスは必然的にこれを蚱可し、したがっお匕き起こすず信じおいるため、すぐに抂念を拒吊する人々がいるこずに気付きたしたそれが解決するよりも問題。 これは定矩に暗黙的に含たれおいたすが、明瀺的に蚀及するず、倚くの䞍芁な前埌が短絡したす。 それぱむリアスの新しい提案の゚むリアスFAQに含たれおいるかもしれたせんが、それがこのスレッドの結果である必芁がありたす。

@Merovius゚クスポヌトされたパッケヌゞグロヌバル

パッケヌゞのバヌゞョンnが䞎えられた堎合p 、

package p
var Global = 0

バヌゞョンn + 1では、ゲッタヌずセッタヌを導入でき、倉数は非掚奚になりたした

package p
//Deprecated: use GetGlobal and SetGlobal.
var Global = 0
func GetGlobal() int {
    return Global
}
func SetGlobal(n int) {
   Global = n
}

バヌゞョンn + 2は、 Global゚クスポヌト解陀できたす。

package p
var global = 0
func GetGlobal() int {
    return global
}
func SetGlobal(n int) {
   global = n
}

挔習は読者に任せたす。 globalぞのアクセスをn + 2のミュヌテックスでラップし、 GetGlobal()を廃止しお、より慣甚的なGlobal()を優先するこずもできたす。

これは迅速な修正ではありたせんが、問題を軜枛するため、コヌドの段階的な修埩にはfunc゚むリアスたたは珟圚の回避策のみが厳密に必芁です。

@rsc芁玄から陀倖した゚むリアスの簡単な䜿甚

@jimmyfrascheあなたは正しいです。 ゲッタヌずセッタヌを䜿甚するずいうアむデアは奜きではありたせんが構造䜓フィヌルドに䜿甚したくないのず同じように、もちろん、あなたの分析は正しいです。

゚むリアスの非修埩䜿甚ドロップむン眮換パッケヌゞの䜜成などに぀いおは泚意が必芁ですが、var-aliasesの堎合は匱くなるず思いたす。

@Meroviusはすべおの点で同意したした。 私もそれに぀いおは満足しおいたせんが、論理v☹vに埓う必芁がありたす

@niemeyerは、叀いものず新しいものの䞡方が同じ名前で眲名が異なるメ゜ッドを持぀タむプの移行をアダプタヌがどのように支揎するかを明確にできたす。 メ゜ッドに匕数を远加したり、匕数のタむプを倉曎したりするこずは、コヌドベヌスの䞀般的な進化のように思われたす。

@rogpeppeこれはたさに今日の出来事であるこずに泚意しおください。

type two one

これにより、 oneずtwo独立したタむプになり、 interface{}反映しおいるかどうかに関係なく、それが衚瀺されたす。 oneずtwo間で倉換するこずもできたす。 䞊蚘のアダプタヌの提案は、アダプタヌの最埌のステップを自動化するだけです。 あなたは耇数の理由で提案を気に入らないかもしれたせんが、それに぀いお矛盟するこずは䜕もありたせん。

@iand type two oneの堎合ず同様に、2぀のタむプには完党に独立したメ゜ッドセットがあるため、名前の䞀臎に぀いお特別なこずは䜕もありたせん。 叀いコヌドベヌスが移行される前は、以前のタむプ珟圚はアダプタヌの叀い眲名を䜿甚したたたになりたす。 新しいタむプを䜿甚する新しいコヌドは、新しい眲名を䜿甚したす。 新しいタむプの倀を叀いコヌドに枡すず、コンパむラヌは埌者が前者のアダプタヌであるこずを認識し、それぞれのメ゜ッドセットを䜿甚するため、自動的にそれを適応させたす。

@niemeyer完党に指定されおいない、これらのアダプタヌの背埌に隠れおいる倚くの耇雑さがあるようです。 この時点で、型゚むリアスの単玔さが圌らに有利に働くず私は思いたす。 私はタむプ゚むリアスのためだけに曎新する必芁があるすべおのものをリストするために座った、そしおそれは非垞に長いリストである。 アダプタヌのリストは確かに長くなりたすが、私はただすべおの詳现を完党には理解しおいたせん。 完党な提案を䜜成したい堎合は、今のずころタむプ゚むリアスを実行し、比范的重いアダプタヌに぀いおの決定を埌で任せるこずをお勧めしたすただし、ドラゎンがそこに朜んでいないこずに懐疑的です 。

@jimmyfrasche゚むリアスのメ゜ッドに関しおは、確かに゚むリアスは通垞のメ゜ッド定矩の制限をバむパスするこずを蚱可したせん。パッケヌゞがタむプT1 = otherpkg.T2を定矩する堎合、otherpkg.T2でメ゜ッドを盎接定矩できないのず同様に、T1でメ゜ッドを定矩できたせん。 ただし、パッケヌゞがタむプT1 = T2䞡方ずも同じパッケヌゞ内を定矩しおいる堎合、答えはあたり明確ではありたせん。 制限を導入するこずはできたすが、ただその必芁性は明らかではありたせん。

トップレベルのディスカッションの抂芁を曎新したした。 倉曎点

  • GothamGoビデオぞのリンクを远加したした
  • @jbaごずに、可胜な䜿甚法ずしお「省略圢の長い名前」を远加したした。
  • @Meroviusに埓っお、暙準ラむブラリの制限に察する匕数ずしおx / image / drawを远加したした。
  • @jimmyfrascheごずに、゚むリアスのメ゜ッドに関するテキストを远加したした。

デザむンドキュメントが远加されたした golang.org/design/18130-type-alias

1週間前の堎合ず同様に、タむプ゚むリアスに぀いおはただ䞀般的なコンセンサスがあるようです。 ロバヌトず私は、チェックむンしたばかりの正匏な蚭蚈ドキュメントを䜜成したした䞊蚘のリンク。

提案プロセスに続いお、この問題に関する提案に぀いおの実質的なコメントを_ここ_に投皿しおください。 スペル/文法/ etcは、Gerritコヌドレビュヌペヌゞhttps://go-review.googlesource.com/#/c/34592/に移動でき

「埋め蟌みぞの圱響」を再考しおいただきたいず思いたす。 これは、段階的なコヌド修埩のための型゚むリアスの䜿いやすさを制限したす。 ぀たり、 p1がタむプtype T1 = T2名前を倉曎し、パッケヌゞp2が構造䜓にp1.T2を埋め蟌んだ堎合、その定矩をp1.T1に曎新するこずはできたせん。 p3が埋め蟌み構造䜓を名前で参照する可胜性があるため。 p2 、その埌に切り替えるこずはできたせんp1.T1壊すこずなく、 p3 。 p3は、珟圚のp2を壊さずに、名前をp1.T1に曎新するこずはできたせん。

これを回避する方法は、a互換性/非掚奚期間の玄束を、名前で埋め蟌みフィヌルドを参照しないコヌドに䞀般的に制限するか、b個別の非掚奚ステヌゞを远加するこずです。したがっお、 p1远加type T1 = T2ず非難するT2 、その埌に、 p2 䟋えばを参照非難するs2.T2名で、すべおの茞入p2修埩されたすそうしないず、 p2が切り替わりたす。

さお、理論的には、問題は無期限に再発する可胜性がありたす。 p4はp3むンポヌトする可胜性があり、それ自䜓がp2からの型を埋め蟌みたす。 p3も、2回埋め蟌たれたフィヌルドを名前で参照するために、非掚奚期間が必芁であるように思われたすか その堎合、最も内偎の非掚奚期間は埮小になるか、最も倖偎の非掚奚期間は無限になりたす。 しかし、問題を再垰的ず芋なさなくおも、b時間を蚈るのはかなり難しいように思われたす p2の非掚奚期間はp1非掚奚期間に完党に含たれる必芁がありたすに少なくずも2Tを遞択する必芁がありたす。これにより、リリヌスが敎列したす。

a私にも実甚的ではないようです。 たずえば、型に*byte.Buffer埋め蟌たれおいお、そのフィヌルドを蚭定したいたたはそのバッファヌを他の関数に枡したい堎合、名前で参照せずにそれを行う方法はありたせんstructinitializersを䜿甚する堎合を陀く名前がないず、互換性の保蚌も倱われたす:)。

゚むリアスずしおbyteずruneず互換性があるこずの魅力を理解しおいたす。 しかし、個人的には、段階的な修埩のために型゚むリアスの有甚性を維持するこずの二次的なものず考えおいたす。 䞡方を取埗するアむデアのおそらく悪い䟋は、゚クスポヌトされた名前の堎合、任意の゚むリアスを䜿甚しお埋め蟌みフィヌルドを参照できるようにするこずず、゚クスポヌトされおいない名前本質的に同じパッケヌゞに制限されおいるため、䜜成者の制埡䞋にあるです。 珟圚提案されおいるセマンティクスを維持したすか はい、私もこの区別が嫌いです。 倚分誰かがより良い考えを持っおいたす。

゚むリアスの@rscreメ゜ッド

䞡方ずも同じパッケヌゞで定矩されおいるタむプTの゚むリアスであるタむプSがあり、Sでメ゜ッドを定矩できる堎合、Tが別のパッケヌゞで定矩されおいるpFの゚むリアスであるずしたらどうでしょうか。 それも明らかに倱敗するはずですが、考慮すべき゜ヌスの匷制、実装、および可読性には埮劙な点がありたすTがSずは異なるファむルにある堎合、Tでメ゜ッドを定矩できるかどうかはすぐにはわかりたせん。 Tの定矩。

ルヌル type T = S堎合、 Tメ゜ッドを宣蚀するこずはできたせんは絶察的であり、゜ヌスの゜ヌスを調査しなくおも、゜ヌスのその1行から適甚されるこずが明らかです。 S、゚むリアスシチュ゚ヌションの゚むリアスの堎合ず同じように。

さらに、ロヌカルの型゚むリアスでメ゜ッドを蚱可するず、型゚むリアスず型定矩の区別が曖昧になりたす。 ずにかくメ゜ッドはSずTの䞡方で定矩されるので、䞀方にしか蚘述できないずいう制限は、衚珟できるものを制限したせん。 それは物事をより単玔でより均䞀に保぀だけです。

@jimmyfrasche type T1 = T2を蚘述しおいお、T2が同じパッケヌゞに含たれおいる堎合、T2ずいう名前はおそらく非掚奚になっおいたす。 その堎合、godocでのT2の発生をできるだけ少なくする必芁がありたす。 したがっお、すべおのメ゜ッドをfunc (T1) M()ずしお宣蚀したいず思いたす。

@jbaは、゚むリアスのメ゜ッドがその゚むリアスで宣蚀されおいるこずを報告するgodocの倉曎であり、゜ヌスの可読性を倉曎するこずなく、その芁件を満たしたす。 䞀般に、゚むリアシングや埋め蟌みが含たれる堎合、特に型が別のパッケヌゞからのものである堎合は、godocが型の完党なメ゜ッドセットを衚瀺するず䟿利です。 この問題は、蚀語セマンティクスではなく、よりスマヌトなツヌルで解決する必芁がありたす。

@jbaその堎合、゚むリアスの方向を逆にしないのはなぜですか type T2 = T1では、同じパッケヌゞ構造でT1メ゜ッドを定矩できたす。 唯䞀の違いは、 reflectパッケヌゞによっお報告されるタむプ名です。゚むリアスを远加する前に、名前に䟝存しない呌び出しサむトを名前に䟝存しないように修正するこずで、移行を開始できたす。

@jimmyfrasche提案曞から

「T1はT2を蚘述する別の方法であるため、独自のメ゜ッド宣蚀のセットはありたせん。代わりに、T1のメ゜ッドセットはT2のメ゜ッドセットず同じです。少なくずも最初の詊行では、T1を次のように䜿甚するメ゜ッド宣蚀に察する制限はありたせん。同じ宣蚀でT2を䜿甚しお提䟛されたレシヌバヌタむプは

メ゜ッドレシヌバヌタむプずしおpFを䜿甚するこずは決しお有効ではありたせん。

@mdempskyはっきりしおいたせんでしたが、無効だず蚀っおいたした。

私のポむントは、その特定のコヌド行を芋るだけでは、それが有効かどうかがはっきりしないずいうこずです。

type S = T䞎えられた堎合、 Tも調べお、別のパッケヌゞのタむプを゚むリアスする゚むリアスでもないこずを確認する必芁がありたす。 唯䞀の利点は耇雑さです。

゚むリアスのメ゜ッドを垞に犁止する方が簡単で読みやすく、䜕も倱うこずはありたせん。 玛らわしいケヌスが頻繁に発生するこずはないず思いたすが、他の堎所で、たたは別の同等のアプロヌチではうたく凊理できないものが埗られない堎合に、その可胜性を玹介する必芁はありたせん。

@Merovius

p1が型タむプT1 = T2の名前を倉曎し、パッケヌゞp2がp1.T2を構造䜓に埋め蟌む堎合、むンポヌタヌp3が埋め蟌たれた構造䜓を名前で参照する可胜性があるため、その定矩をp1.T1に曎新するこずはできたせん。

倚くの堎合、匿名フィヌルドを名前付きフィヌルドに倉曎し、メ゜ッドを明瀺的に転送するこずで、この問題を回避するこずができたす。 ただし、これぱクスポヌトされおいないメ゜ッドでは機胜したせん。

別のオプションは、補償するために2番目の機胜を远加するこずかもしれたせん。 フィヌルドのメ゜ッドセットを匿名にせずにたたは明瀺的な名前倉曎を䜿甚しお採甚できる堎合は、基になる型が倉曎されおもフィヌルド名を倉曎しないでおくこずができたす。

あなたの䟋からの宣蚀を考えおみたしょう

package p2

type S struct {
  p1.T2
}

補正機胜の1぀は、「フィヌルド゚むリアス」である可胜性がありたす。これは、゚むリアスを入力するのず同様の構文に埓いたす。

package p2

type S struct {
  p1.T1
  T2 = T1  // field T2 is an alias for field T1.
}

var s S  // &s.T2 == &s.T1

別の補正機胜は「委任」である可胜性がありたす。これは、匿名フィヌルドのメ゜ッドセットを明瀺的に採甚したす。

package p2

type S struct {
  T2 p1.T1 delegated  // T2 is a field of type T1.
  // The method set of S includes the method set of T1 and forwards those calls to field T2.
}

私はフィヌルド゚むリアスを自分で奜むず思いたす。なぜなら、それらは別の皮類の段階的な修埩も可胜にするからです。ポむンタ゚むリアスや䞀貫性のバグを導入せずに構造䜓のフィヌルドの名前を倉曎するこずです。

@Merovius䞻な問題は、タむプの名前が゚むリアスによっお倉曎された堎合です。

私はこれを完党には考慮しおいたせん—かろうじお通過するだけで、ただランダムな考えです

パッケヌゞに名前を付けおそれを埋め蟌む゚むリアスを導入するずどうなりたすか

それが䜕かを修正するかどうかはわかりたせんが、ルヌプを壊すのに時間がかかるかもしれたせんか

@bcmillsその回避策に぀いおは考えおいたせんでした、ありがずう。 ゚クスポヌトされおいないメ゜ッドに関する譊告は、実際にはめったに発生しないため、䞀般的に私の意芋を揺るがすこずはないず思いたす完党に理解しおいない限り。それが圹立぀ず思われる堎合は、遠慮なく明確にしおください。 。 これ以䞊の倉曎を積み重ねるこずは正圓化されないず思いたすたたは良い考えです。

@Merovius考えれば考えるほど、フィヌルド゚むリアスのアむデアが奜きになりたす。

メ゜ッドを明瀺的に転送するこずは、゚クスポヌトされたずしおも面倒であり、他の皮類のリファクタリングを壊したすたずえば、埋め蟌み型にメ゜ッドを远加し、それを埋め蟌む型が同じむンタヌフェむスを満たし続けるこずを期埅したす。 たた、構造䜓フィヌルドの名前を倉曎するこずも、コヌドの段階的な修埩を可胜にするずいう䞀般的な範囲に含たれたす。

@Merovius

p1が型タむプT1 = T2の名前を倉曎し、パッケヌゞp2がp1.T2を構造䜓に埋め蟌む堎合、むンポヌタヌp3が埋め蟌たれた構造䜓を名前で参照する可胜性があるため、その定矩をp1.T1に曎新するこずはできたせん。 その堎合、p2はp3を壊さずにp1.T1に切り替えるこずはできたせん。 p3は、珟圚のp2を壊さずに、名前をp1.T1に曎新するこずはできたせん。

あなたの䟋を理解するず、次のようになりたす。

package p1

type T2 struct {}
type T1 = T2
package p2

import "p1"

type S struct {
  p1.T2
  F2 string // see below
}

これは、構造䜓フィヌルドの名前を倉曎したい䞀般的なケヌスの特定の䟋にすぎないず思いたす。 S.F2の名前をS.F1に倉曎する堎合も、同じ問題が圓おはたりたす。

この特定のケヌスでは、ロヌカルタむプ゚むリアスでp1の新しいAPIを䜿甚するようにパッケヌゞp2を曎新する堎合がありたす。

package p2

import "p1"

type T2 = p1.T1

type S struct {
  T2
}

もちろん、これは長期的な解決策ずしおは適切ではありたせん。 p2が゚クスポヌトされたAPIを倉曎しおT2名を削陀する必芁があるずいう事実を回避する方法はないず思いたすが、フィヌルドの名前倉曎ず同じように進行したす。

「パッケヌゞ間でのタむプの移動」に関する泚意事項。 その定匏化は少し問題がありたせんか

私が理解しおいる限り、この提案では、新しい名前を介しお別のパッケヌゞにあるオブゞェクト定矩を「参照」するこずができたす。

オブゞェクト定矩は移動したせんね。 そもそも゚むリアスを䜿甚しおコヌドを蚘述しない限り、ナヌザヌは、draw pkgの堎合ず同様に、゚むリアスが参照する堎所を自由に倉曎できたす。

@atdiar別のパッケヌゞのタむプを参照するこずは、タむプを移動するステップずしお䜿甚できたす。 はい、゚むリアスはタむプを移動したせんが、移動するためのツヌルずしお䜿甚できたす。

@Meroviusこれを行うず、リフレクションずプラグむンが砎損する可胜性がありたす。

@atdiar申し蚳ありたせんが、あなたが䜕を蚀おうずしおいるのかわかりたせん。 このスレッドの元のコメント、そこにリンクされおいる段階的な修埩に関する蚘事、およびこれたでの議論を読んだこずがありたすか これたで考慮されおいなかった議論を議論に加えようずしおいるのであれば、もっず明確にする必芁があるず思いたす。

最埌に、有甚でよく曞かれた提案。 型゚むリアスが必芁です。型゚むリアスなしで単䞀のAPIを䜜成するこずには倧きな問題がありたす。これたでのずころ、それを実珟するためにあたり奜きではない方法でコヌドを䜜成する必芁がありたす。 これはgov1.8に含たれおいる必芁がありたすが、手遅れになるこずはないので、1.9に進んでください。

@Merovius
私はパッケヌゞ間の「タむプの移動」に぀いお明瀺的に話しおいる。 オブゞェクト定矩を倉曎したす。 たずえば、pkg Reflectでは、䞀郚の情報はオブゞェクトが定矩されたパッケヌゞに関連付けられおいたす。
定矩を移動するず、壊れるこずがありたす。

@katarasそれは本圓に良いドキュメントやコメントに぀いおではなく、単に型定矩を移動しおはならないずいうこずです。 ゚むリアスの提案に感謝しおいるのず同じくらい、人々がそれができるず思っおいるのではないかず心配しおいたす。

@atdiarもう䞀床、元のコメントずこれたでの議論からの蚘事を読んでください。 移動タむプず懞念事項ぞの察凊方法は、このスレッドの䞻な懞念事項です。 ラスの蚘事があなたの懞念に適切に察凊しおいるず思わない堎合は、圌の説明が満足のいくものではない理由を具䜓的に説明しおください。 :)

@kataras私は個人的には同意したすが、この機胜がどれほど重芁であるかを単玔に䞻匵するこずは、特に圹立぀ずは思いたせん。 人々の懞念に察凊するために建蚭的な議論をする必芁がありたす。 :)

@Meroviusドキュメントを読みたした。 それは私の質問に答えたせん。 私は十分に明確にしたず思いたす。 これは、以前の゚むリアス提案を実装するこずを思いずどたらせたのず同じ問題に関連しおいたす。

@atdiar少なくずも、わかりたせん。 タむプを移動するず問題が発生するずおっしゃっおいたす。 提案は、゚むリアスを䜿甚しお段階的な修埩でこのような砎損を回避し、叀いタむプを䜿甚するコヌドがなくなるたで各逆䟝存関係を曎新しおから、叀いタむプを削陀する方法に関するものです。 「リフレクションずプラグむン」が壊れおいるずいうあなたの䞻匵が、これらの仮定の䞋でどのように成り立぀かはわかりたせん。 あなたが仮定に疑問を呈したいのであれば、それはすでに議論されおいたす。

たた、゚むリアスが1.8に入るのを劚げる問題が、あなたの蚀ったこずにどのように関係しおいるかわかりたせん。 私の知る限り、それぞれの問題は17746ず17784です。 埋め蟌みの問題私は同意したせんが、砎損や反省に関連しおいるず解釈される可胜性がありたすに぀いお蚀及しおいる堎合、それは正匏な提案で扱われたすただし、䞊蚘を参照しおください、提案された解決策はもっず議論する䟡倀があるず思いたすそしお、あなたはそれが信じられない理由に぀いお具䜓的にする必芁がありたす。

それで、申し蚳ありたせんが、いいえ、あなたは十分に具䜓的ではありたせんでした。 あなたが蚀及しおいる「以前の゚むリアス提案の実装を思いずどたらせたのず同じ問題」の問題番号がありたすか。これは、理解を助けるために、これたでに述べたこずに関連しおいたすか。 あなたが話しおいる砎損の具䜓䟋を挙げおいただけたすかこのアップスレッドの䟋を参照しおください。䞀連のパッケヌゞ、型定矩、およびいく぀かのコヌドを瀺し、提案どおりに倉換したずきにどのように砎損するかを説明しおください。 あなたがあなたの懞念に察凊したいのなら、あなたは本圓に他の人が最初にそれらを理解するのを助ける必芁がありたす。

@Meroviusでは、これらの䟝存関係の1぀がreflect.Type.PkgPathを調べおいる掚移的な䟝存関係の堎合、どうなりたすか
これは、埋め蟌みの問題で発生するのず同じ問題です。

@atdiar申し蚳ありたせんが、これたでのこのスレッドでの議論ずこの提案の内容を考慮するず、これがどのように理解できる懞念であるかはわかりたせん。 私は今、この特定のサブスレッドから抜け出し、あなたの異議をよりよく理解しおいるかもしれない他の人に、それに察凊する機䌚を䞎えたす。

簡朔に蚀い換えたす。

問題は、型定矩がそれ自䜓の堎所をハヌドコヌドしおいるずいう事実を考えるず、型の同等性に関するものです。
型の同等性は実行時にテストされる可胜性があり、テストされるため、型の移動がいかに簡単であるかはわかりたせん。

この「タむプの移動」のナヌスケヌスは、離れた堎所にある倚くのパッケヌゞを壊しおしたう可胜性があるずいう譊告を発しおいるだけです。 プラグむンに぀いおも同様の心配がありたす。

同じように、パッケヌゞ内のポむンタヌのタむプを倉曎するず、他の倚くのパッケヌゞが壊れたす。その䞊列凊理によっお状況が明確になる堎合です。

@atdiar繰り返したすが、この問題は2぀のステップで型を移動するこずに関するものです。最初に叀い堎所を非掚奚にし、逆の䟝存関係を曎新しおから、型を移動したす。 _もちろん_タむプを移動するだけで問題が発生したすが、これはこの問題の原因ではありたせん。 これは、それを行うための段階的なマルチステップ゜リュヌションを可胜にするこずです。 ここで提案された゜リュヌションのいずれかがこのマルチステッププロセスを有効にしないずいう懞念がある堎合は、正確に、段階的な修埩コミットの合理的なシヌケンスが砎損を防ぐこずができない状況を説明しおください。

@niemeyer

これにより、1぀ず2぀の独立したタむプが䜜成され、むンタヌフェむス{}を反映するかどうかに関係なく、それが
分かりたすか。 1ず2の間で倉換するこずもできたす。 䞊蚘のアダプタヌの提案はそれを最埌にしたす
アダプタヌの自動ステップ。 あなたは耇数の理由で提案を気に入らないかもしれたせんが、䜕もありたせん
それに぀いお矛盟しおいる。

間で倉換するこずはできたせん

 func() one

ず

func() two

@Meroviusおそらく、

明確にするために、私ぱむリアスの提案に反察しおいるのではなく、「パッケヌゞ間でタむプを移動する」ずいう定匏化に反察しおいたす。これは、ただ安党であるこずが蚌明されおいないナヌスケヌスを意味したす。

@jimmyfrasche re予枬可胜性のメ゜ッドオン゚むリアスの劥圓性

func (t T) M()が有効な堎合もあれば、無効な堎合もありたす。 人々はこれらの境界をあたり頻繁に抌し出さないので、それはあたり出おきたせん。 ぀たり、実際にはうたく機胜したす。 https://play.golang.org/p/bci2qnldej。 いずれにせよ、これは_可胜性のある_制限のリストにありたす。 考えられるすべおの制限ず同様に、耇雑さが増すため、その耇雑さを远加する前に、具䜓的な実䞖界の蚌拠を確認する必芁がありたす。

@Merovius 、名前の再埋め蟌み

私は状況が完党ではないこずに同意したす。 ただし、io.ByteBufferぞの参照でいっぱいのコヌドベヌスがあり、それをbytes.Bufferに移動したい堎合は、導入できるようにしたいず思いたす。

package io
type ByteBuffer = bytes.Buffer

io.ByteBufferぞの既存の参照を曎新せずに。 タむプ定矩を゚むリアスに眮き換えた結果、io.ByteBufferが埋め蟌たれおいるすべおの堎所で、フィヌルドの名前が自動的にBufferに倉曎された堎合、私は䞖界を壊し、段階的な修埩はありたせん。 察照的に、埋め蟌たれたio.ByteBufferの名前がただByteBufferである堎合は、䜿甚法を䞀床に1぀ず぀曎新しお、段階的に修埩するこずができたす耇数の手順を実行する必芁がある可胜性がありたすが、これも理想的ではありたせん。

これに぀いおは、17746である皋床詳しく説明したした。 私はもずもず、埋め蟌たれたio.ByteBuffer゚むリアスの名前がBufferであるずいう偎にいたしたが、䞊蚘の議論は私が間違っおいるず確信したした。 特に@jimmyfrascheは、埋め蟌たれたものの定矩に応じおコヌドが倉曎されないこずに぀いお、いく぀かの良い議論をしたした。 埋め蟌たれた゚むリアスを完党に犁止するのは難しいず思いたす。

あなたの䟋のp2には回避策があるこずに泚意しおください。 p2がio.ByteBufferを参照せずにByteBufferずいう名前の埋め蟌みフィヌルドを本圓に必芁ずする堎合は、次のように定矩できたす。

type ByteBuffer = bytes.Buffer

次に、io.ByteBufferの代わりにByteBuffer぀たり、p2.ByteBufferを埋め蟌みたす。 それも完璧ではありたせんが、修理を続けるこずができるずいうこずです。

これが完党ではなく、フィヌルドの名前倉曎が䞀般的にこの提案で察凊されおいないのは間違いありたせん。 埋め蟌みは基になる名前に敏感であっおはならず、「名前NずしおXを埋め蟌む」ためのある皮の構文が必芁である可胜性がありたす。 埌でフィヌルド゚むリアスを远加する必芁がある堎合もありたす。 どちらも先隓的に合理的なアむデアのように思われ、おそらく䞡方ずも別々である必芁があり、埌の提案は必芁性の実際の蚌拠に基づいお評䟡されたす。 タむプ゚むリアスが、フィヌルド゚むリアスの欠劂が倧芏暡なリファクタリングの次の倧きな障害ずなる点に到達するのに圹立぀堎合、それは進歩するでしょう

/ cc @neildおよび@bcmills

@atdiar 、はい、

@rsc私が念頭に眮いおいたのは、a゚むリアスずその定矩タむプの䞡方を同じ構造䜓に埋め蟌むこずを犁止するbからのあいたいさを防ぐため、b゜ヌスコヌド内のいずれかの名前でフィヌルドを参照できるようにする、cいずれかを遞択するたたは生成されたタむプ情報/リフレクションなどのその他どちらでも構いたせん。

これは、私が説明しようずした皮類の砎損を回避するのに圹立぀ず同時に、遞択が必芁な堎合の明確な遞択を行うのに圹立぀ず、私は手を振っお䞻匵したす。 そしお、個人的には、リフレクションに䟝存するコヌドを壊さないこずよりも、リフレクションに䟝存するコヌドを壊さないこずに関心がありたす。

あなたのByteBuffer匕数を理解しおいるかどうかは今のずころわかりたせんが、私も長い仕事の終わりにいるので、それ以䞊説明する必芁はありたせん。玍埗がいかない堎合は、最終的に応答したす:)

@Merovius単玔なルヌルを詊しお、より耇雑なルヌルを導入する前に、どこたで到達できるかを確認するのは理にかなっおいるず思いたす。 必芁に応じお、埌でaずbを远加できたす。 cは䜕があっおも䞎えられたす。

私は、bが特定の状況では良い考えであるかもしれないが、他の状況ではそうではないかもしれないこずに同意したす。 前述の「1぀のパッケヌゞAPIを耇数の実装パッケヌゞに構造化する」ナヌスケヌスにタむプ゚むリアスを䜿甚しおいる堎合は、゚むリアスを埋め蟌んで他の名前内郚パッケヌゞに含たれおいる可胜性がありたすを公開したくない堎合がありたす。それ以倖の堎合、ほずんどのナヌザヌはアクセスできたせん。 もっず経隓を積んでいただければず思いたす。

@rsc

おそらく、゚むリアス可胜性に関するパッケヌゞレベルの情報をオブゞェクトファむルに远加するず圹立぀堎合がありたす。
goプラグむンが適切に機胜し続ける必芁があるかどうかを考慮に入れながら。

@Merovius @rsc

a゚むリアスずその定矩型の䞡方を同じ構造䜓に埋め蟌むこずを犁止する

倚くの堎合、埋め蟌みがメ゜ッドセットず盞互䜜甚する方法の結果ずしお、これはすでに犁止されおいるこずに泚意しおください。 埋め蟌み型に空でないメ゜ッドが蚭定されおいお、それらのメ゜ッドの1぀が呌び出された堎合、プログラムはコンパむルに倱敗したすhttps//play.golang.org/p/XkaB2a0_RK。

したがっお、二重埋め蟌みを犁止する明瀺的なルヌルを远加しおも、ごく䞀郚のケヌスでのみ違いが生じるように思われたす。 私には耇雑にする䟡倀がないようです。

代わりに代数型ずしお型゚むリアスにアプロヌチし、型のセットぞの゚むリアスをサポヌトしお、コンパむル時の型チェックず同等の空のむンタヌフェむスをボヌナスずしお取埗しおみたせんか

type Stringeroonie = {string,fmt.Stringer}

@ j7b

代わりに代数型ずしお型゚むリアスにアプロヌチし、䞀連の型ぞの゚むリアスをサポヌトしおみたせんか

゚むリアスは、意味的および構造的に元のタむプず同等です。 代数的デヌタ型はそうではありたせん。䞀般的な堎合、タむプタグ甚に远加のストレヌゞが必芁です。 Goむンタヌフェヌス型はすでにその型情報を持っおいたすが、構造䜓や他の非むンタヌフェヌス型は持っおいたせん。

@bcmills

これは誀った掚論かもしれたせんが、タむプTの゚むリアスAは、Aをむンタヌフェむス{}ずしお宣蚀し、タむプAの倉数が宣蚀されおいるスコヌプでコンパむラにタむプAの倉数を透過的に倉換させるこずず同等であるため、問題に取り組むこずができるず思いたした。 、これはほずんど線圢のコンパむル時コストであり、明確であり、 type T =構文を䜿甚しお代数を含むコンパむラ管理の疑䌌型の基瀎を䜜成し、コンパむル時に䞍倉の参照などの型を実装できるようにするこずもできたす。ナヌザヌコヌドに関する限り、むンタヌフェヌス{}は「内郚」にすぎたせん。

その䞀連の思考の欠陥はおそらく無知の産物であり、私は抂念の実甚的な蚌明を提䟛する立堎にないので、それが䞍十分であるこずを受け入れお延期するこずを嬉しく思いたす。

@ j7b 1぀の段階的な修埩問題の解決策があるADTであっおも、独自の問題を䜜成したす。 䟝存関係を壊さずにADTのメンバヌを远加たたは削陀するこずは䞍可胜です。 したがっお、本質的には、解決するよりも倚くの問題を䜜成するこずになりたす。

interface {}ずの間で透過的に倉換するずいうあなたの考えは、 []interface{}ような高次の型でも機胜したせん。 そしお最終的には、goの長所の1぀を倱うこずになりたす。それは、ナヌザヌがデヌタレむアりトを制埡できるようにし、代わりにすべおをラップするJavaの凊理を実行するこずです。

ADTはここでの解決策ではありたせん。

@Merovius代数型の構成に名前の倉曎が含たれおいる堎合これは同じの合理的な定矩ず䞀臎したす、それは解決策であり、そのむンタヌフェむス{}はコンパむラが管理する射圱ず遞択の圢匏のプロキシずしお機胜できるず確信しおいたす。説明されおおり、デヌタレむアりトがどのように関連しおいるか、「高次」型をどのように定矩しおいるかはわかりたせん。型は、宣蚀できる堎合は単なる型であり、[] interface {}は単なる型です。

それはさおおき、 type T =は、名前の倉曎を超えた盎感的で䟿利な方法でオヌバヌロヌドされる可胜性があるこずを確信しおいたす。代数型ず公的に䞍倉の参照は最も明癜なアプリケヌションのようです。したがっお、仕様にその構文が蚘茉されおいるこずを願っおいたす。コンパむラが管理するメタ型たたは疑䌌型を瀺し、コンパむラが管理する型が圹立぀可胜性のあるすべおの方法ず、それらの䜿甚法を最もよく衚す構文が考慮されたす。 新しい構文は、修食子ずしお䜿甚するずきにグロヌバルに予玄された単語のセットに関係する必芁がないため、 type A = alias Typeようなものは明確で拡匵可胜です。

@ j7b

それはさおおき、私はポゞティブタむプですT =名前を倉曎するだけでなく、盎感的で䟿利な方法でオヌバヌロヌドされる可胜性がありたす。

私は確かにそうしないこずを望みたす。 今日、Goはほずんどうたく盎亀しおおり、その盎亀性を維持するこずは良いこずです。

今日、Goで新しい型Tを宣蚀する方法はtype T def 。ここで、 defは新しい型の定矩です。 代数的デヌタ型別名タグ付き共甚䜓を実装する堎合、型゚むリアスの構文ではなく、その構文に埓うこずを期埅したす。

私はタむプ゚むリアスの別の芖点サポヌトを投入するのが奜きです。これは、リファクタリング以倖の代替ナヌスケヌスぞの掞察を提䟛する可胜性がありたす。

少し前に戻っお、 type T <a type>の圢匏の通垞の叀いGo型宣蚀がなく、型゚むリアス宣蚀type A = <a type>のみがあるず仮定したしょう。

党䜓像を完成させるために、メ゜ッドが䜕らかの圢で異なる方法で宣蚀されおいるず仮定したしょう-レシヌバヌずしお䜿甚される名前付き型ぞの関連付けではなく、できないためです。たずえば、文字通りメ゜ッドを持぀クラス型の抂念を想像できたす。内郚であるため、メ゜ッドを宣蚀するために名前付き型に䟝存する必芁はありたせん。構造的に同䞀であるがメ゜ッドが異なる2぀の型は、異なる型になりたす。この思考実隓では、詳现は重芁ではありたせん。

そのような䞖界では、今曞いおいるのずほが同じコヌドを曞くこずができるず私は䞻匵したす。゚むリアス型名を䜿甚するので、繰り返す必芁はありたせん。型自䜓は、型でデヌタを䜿甚するこずを確認したす。 -安党な方法。

蚀い換えれば、Goがそのように蚭蚈されおいたずしたら、私たちも抂しお倧䞈倫だったでしょう。

さらに、そのような䞖界では、タむプは構造的に同䞀であれば名前に関係なく同䞀であるため、リファクタリングで発生する問題はそもそも珟れず、必芁もありたせん。蚀語の倉曎。

しかし、珟圚のGoにあるような安党メカニズムはありたせん。タむプの名前を導入しお、これを新しい別のタむプにする必芁があるこずを瀺すこずはできたせん。 それでも、それは本質的に安党メカニズムであるこずを芚えおおくこずが重芁です。

他のプログラミング蚀語では、既存の型ずは異なる新しい型を䜜成するずいう抂念は「ブランディング」ず呌ばれたす。型getはそれに付けられたブランドであり、他のすべおの型ずは異なりたす。 たずえば、Modula-3では、それを実珟するための特別なキヌワヌドBRANDEDたしたたずえば、 TYPE T = BRANDED REF T0はT0ぞの新しい異なる参照を䜜成したす。 Haskellでは、型の前のnewずいう単語も同様の効果がありたす。

代替のGoの䞖界に戻るず、リファクタリングに問題はないが、コヌドの安党性を向䞊させおtype MyBuffer = []byteずtype YourBuffer = []byte衚すようにしたいず思うかもしれたせん。誀っお間違ったものを䜿甚しないように、さたざたなタむプがありたす。 たさにその目的のために、タむプブランディングの圢匏を導入するこずを提案するかもしれたせん。 たずえば、 type MyBuffer = new []byte 、たたはtype MyBuffer = new YourBufferを蚘述しお、MyBufferがYourBufferずは異なるタむプになるようにするこずができたす。

これは本質的に、私たちが今持っおいるものの二重の問題です。 Goでは、初日から、名前が付けられるずすぐに「ブランド」タむプを垞に䜿甚しおいたした。 蚀い換えれば、 type T <a type>は事実䞊type T = new <a type>です。

芁玄するず、既存のGoでは、名前付きタむプは垞に「ブランド化された」タむプであり、タむプの名前だけの抂念がありたせん珟圚はタむプ゚むリアスず呌んでいたす。 他のいく぀かの蚀語では、タむプ゚むリアスが暙準であり、「ブランディング」メカニズムを䜿甚しお、明瀺的に新しい異なるタむプを䜜成する必芁がありたす。

重芁なのは、䞡方のメカニズムが本質的に有甚であり、タむプ゚むリアスを䜿甚しお、最終的に䞡方をサポヌトするために回避できるずいうこずです。

@griesemerその機胜の拡匵は、理想的にはリファクタリングをクリヌンアップする必芁がある最初の゚むリアス提案です。 スコヌプが制限されおいるため、タむプ゚むリアスのみが難しいリファクタリング゚ッゞケヌスを䜜成するのではないかず心配しおいたす。

どちらの提案でも、説明したように名前はGoの型定矩の䞀郚であるため、リンカヌからのコラボレヌションは必芁ないのではないかず疑問に思っおいたす。

私はオブゞェクトコヌドにたったく粟通しおいないので、それは単なるアむデアですが、オブゞェクトファむルにカスタムセクションを远加するこずは可胜のようです。 偶然にも、タむプ名ずその゚むリアスのリンク時に埋められた、ある皮の展開されたリンクリストを保持するこずが可胜であった堎合は、それが圹立぀可胜性がありたす。 ランタむムには、個別のコンパむルを犠牲にするこずなく、必芁なすべおの情報が含たれたす。

゚ラヌメッセヌゞが明確なたたになるように、ランタむムは特定のタむプのさたざたな゚むリアスを動的に返すこずができる必芁があるずいう考えです゚むリアスによっお実行䞭のコヌドず蚘述されたコヌドの間に名前の䞍䞀臎が生じるため。

゚むリアシングの䜿甚を远跡する代わりに、コンテキストパッケヌゞで行われたように、パッケヌゞ間でオブゞェクト定矩を「移動」できるように、具䜓的なバヌゞョン管理ストヌリヌを倧芏暡に䜜成するこずもできたす。 しかし、それはたったく別の問題です。

結局のずころ、むンタヌフェむスず名前の同等性を型に残しおおくこずは、䟝然ずしお良い考えです。
タむプはより倚くの制玄のあるむンタヌフェヌスず芋なすこずができるずいう事実を考えるず、゚むリアスの宣蚀は、スラむスのタむプ名文字列のパッケヌゞごずのスラむスを保持するこずによっお実装する必芁がある/できるようです。

@atdiar 「個別のコンパむル」ず蚀ったずきに私が䜕をするのか

@ j7dは、型システムレベルでは、合蚈型たたは任意の皮類のサブタむプ説明の前半で他の人が提案したようには、特定の皮類の䜿甚にのみ圹立ちたす。 bytes.Bufferをio.Readerのサブタむプず考えるこずができるのは事実です「バッファはリヌダヌです」、たたはあなたの䟋では「文字列はStringeroonieです」。 これらを䜿甚しおより耇雑な型を構築するず、問題が発生したす。 このコメントの残りの郚分では、Goタむプに぀いお説明しおいたすが、蚀語が実際に実装しおいるGoではなく、サブタむプレベルでの基本的な関係に぀いお説明しおいたす。 ただし、Goは基本的な関係ず䞀臎するルヌルを実装する必芁がありたす。

型構築子「型を䜿甚する方法」を蚀うための掟手な方法は、サブタむプの関係を保持する堎合は共倉であり、関係を反転する堎合は反倉です。

関数の結果で型を䜿甚するこずは共倉です。 funcバッファは、funcリヌダヌです。これは、バッファを返すこずは、リヌダヌを返したこずを意味するためです。 関数の匕数で型を䜿甚するこずは、共倉ではありたせん。 funcにはBufferが必芁であり、䞀郚のReaderはBufferではないため、funcBufferはfuncReaderではありたせん。

関数の匕数で型を䜿甚するこずは逆倉です。 funcReaderはfuncBufferです。これは、funcにはReaderのみが必芁であり、BufferはReaderであるためです。 関数の結果で型を䜿甚するこずは、反倉ではありたせん。 funcリヌダヌはfuncバッファヌではありたせん。これは、funcがリヌダヌを返し、䞀郚のリヌダヌがバッファヌではないためです。

この2぀を組み合わせるず、funcReaderReaderはfuncBufferBufferではなく、その逆も同様です。匕数が機胜しないか、結果が機胜しないためです。 これらの線に沿っお機胜する唯䞀の組み合わせは、funcReaderBufferがfuncBufferReaderであるずいうこずです。

䞀般に、funcX1X2がfuncX3X4のサブタむプである堎合、X3はX1のサブタむプであり、同様にX2はX4のサブタむプである必芁がありたす。 T1ずT2を亀換可胜にする゚むリアス䜿甚の堎合、T1がT2のサブタむプであり、T2がT1のサブタむプである堎合にのみ、funcT1T1はfuncT2T2のサブタむプです。 ぀たり、基本的に、T1はT2ず_同じ_タむプであり、より䞀般的なタむプではありたせん。

関数の匕数ず結果を䜿甚したのは、それが暙準的な䟋そしお良い䟋だからですが、耇雑な結果を䜜成する他の方法でも同じこずが起こりたす。 䞀般に、出力の共分散funcT、<-chan T、たたはmap [...] Tなどず入力の共分散funcT、chan <-T、たたはmap [Tなどを取埗したす。 ] ...および入出力の匷制型の同等性funcTT、chan T、* T、[10] T、[] T、struct {Field T}、たたは倉数などタむプTの。 実際、䟋からわかるように、Goで最も䞀般的なケヌスは入力+出力です。

具䜓的には、[]バッファは[]リヌダヌではありたせんファむルを[]リヌダヌに保存できたすが、[]バッファには保存できないため。たた、[]リヌダヌは[]バッファではありたせん[]からフェッチするため。 [] BufferからフェッチするずBufferを返す必芁がありたすが、ReaderはFileを返す堎合がありたす。

これらすべおからの結論は、コヌドがT1たたはT2のいずれかを䜿甚できるように䞀般的なコヌド修埩の問題を解決したい堎合、T1をT2のサブタむプのみにするたたはその逆スキヌムでは実行できないずいうこずです。 それぞれが他のサブタむプである必芁がありたす぀たり、同じタむプである必芁がありたす。そうでない堎合、これらのリストされた䜿甚法の䞀郚は無効になりたす。

぀たり、段階的なコヌド修埩の問題を解決するには、サブタむプ化だけでは䞍十分です。 これが、タむプ゚むリアスが同じタむプに新しい名前を導入する理由です。そのため、サブタむプを詊行する代わりに、T1 = T2になりたす。

このコメントは、2週間前のある皮の「代替可胜なタむプ」の@iandの提案、および基本的にはそれ以降の@griesemerの応答の拡匵にも

トップレベルのディスカッションの抂芁を曎新したした。 倉曎点

  • TODOを削陀しお、アダプタヌに関する議論の芁玄を曎新したした。これはフェヌドアりトしたようです。
  • 埋め蟌みずフィヌルド名の倉曎に関する説明の芁玄を远加したした。
  • 「゚むリアスのメ゜ッド」の抂芁を蚭蚈の質問リストから独自のセクションに移動し、最近のコメントを含むように拡匵したした。
  • リフレクションを䜿甚したプログラムぞの圱響に関する議論の芁玄を远加したした。
  • 個別のコンパむルに関する議論の芁玄を远加したした。
  • さたざたなサブタむピングベヌスのアプロヌチの説明の芁玄を远加したした。

個別のコンパむルに関する@rsc 、私のコメントは、型定矩が゚むリアスのリストを保持する必芁があるか個別のコンパむル芁件のために倧芏暡に扱いにくい、たたは各゚むリアスが次の゚むリアス名のリストを繰り返し䜜成するこずを含むかどうかに関連しおいたすむンポヌトグラフ。すべお、タむプ定矩で指定された指定された初期タむプ名に関連しおいたす。 そしお、ランタむムがその情報にアクセスできるように、その情報をどこにどのように保持するか。

@atdiarシステムのどこにもそのような゚むリアス名のリストはありたせん。 ランタむムはそれにアクセスできたせん。 ゚むリアスは実行時に存圚したせん。

@rscハァッ、ごめんなさい。 私は頭の䞭で最初の゚むリアスの提案に固執しおいお、funcの゚むリアシングに぀いお考えおいたしたタむプの゚むリアシングに぀いお議論しおいる間。 その堎合、コヌド内の名前ず実行時の名前の間に䞍䞀臎が生じたす。
その堎合、runtime.Frameの情報をロギングに䜿甚するには、再考が必芁になりたす。
私に構わずに。

@rsc再芁玄しおございたす。 埋め蟌たれたフィヌルド名はただ私を苛立たせたす。 提案されたすべおの回避策は、叀い名前を維持するために恒久的な応急修理に䟝存しおいたす。 このコメントのより倧きなポむント、぀たりこれはフィヌルドの名前倉曎の特殊なケヌスであり、これも䞍可胜であるずいうこずですが、これは確かに別の問題ず芋なされそしお解決されなければならないこずを私に確信させたす。 段階的な修埩のためにフィヌルドの名前倉曎をサポヌトするために、芁求/提案/ディスカッションに察しお別の問題を開くこずは意味がありたすかおそらく同じgoリリヌスで察凊されたす

@Merovius 、フィヌルド名の倉曎のための段階的なコヌド修埩がシヌケンスの次の問題のように芋えるこずに同意したす。 その議論を始めるために、誰かが実際の䟋のスむヌトを集める必芁があるず思いたす。それは、それが広範囲にわたる問題であるずいう蚌拠を埗るず同時に、朜圚的な解決策をチェックするためです。 珟実的には、同じリリヌスでそれが起こっおいるずは思いたせん。

2週間先から戻っおきたした。 議論は収束したようです。 2週間前のディスカッションの曎新でさえ、かなりマむナヌでした。

私は私たちに提案したす

  • 䞊蚘の問題の暫定的な解決策ずしお、タむプ゚むリアスの提案を受け入れたす。
    Go 1.9の開始時2月1日に実装を詊す準備ができおいる堎合。
  • dev.typealias devブランチを䜜成しお、CLを今すぐ確認し1月、Go1.9の開始時にマスタヌにマヌゞできるようにしたす。
  • Go 1.9フリヌズの開始近くにタむプ゚むリアスを保持するこずに぀いお最終決定を䞋したすGo 1.8サむクルの䞀般化された゚むリアスに察しお行ったように。

+1

この倉曎の背埌にある議論の歎史に感謝したす。 実装されおいるずしたしょう。 間違いなく、それはコア機胜ではなく、蚀語のかなりフリンゞな詳现になるでしょう。 そのため、実際の䜿甚頻床に䞍釣り合いな蚀語ずツヌルが耇雑になりたす。 たた、蚀語が誀っお悪甚される可胜性のある衚面積が増えたす。 そのため、慎重すぎるのは良いこずであり、これたでにたくさんの議論があったこずをうれしく思いたす。

@Merovius 私の投皿を線集しおすみたせん 誰も読んでいないず思った。 最初にこのコメントで、 gorenameツヌルのようなツヌルがすでに存圚する堎合、この蚀語の倉曎が必芁であるこずに懐疑的な芋方を瀺したした。

@ jcao219これは以前に議論されたしたが、驚くべきこずに、私はこれをここですぐに芋぀けるこずができないようです。 䞀般的な゚むリアス16339の元のスレッドず、関連するgolang-nutsスレッドで詳现に説明されおいたす。 ぀たり、この皮のツヌルは、修埩コミットを準備する方法のみを扱い、砎損を防ぐために倉曎を順序付ける方法は扱いたせん。 倉曎がツヌルによっお行われたか人間によっお行われたかにかかわらず、珟圚、コヌドを壊さないコミットのシヌケンスはありたせんこの問題の元のコメントず関連するドキュメントは、このステヌトメントをより正圓化したす-深さ。

より自動化されたツヌルたずえば、goツヌルなどに統合されおいるの堎合、元のコメントは、「これは、蚀語の倉曎ではなく、ツヌルたたはコンパむラのみの倉曎である可胜性がありたすか」ずいう芋出しの䞋でこれに察凊したす。

結論ずしお、倉曎が実装されたずしたしょう。 間違いなく、それはコア機胜ではなく、蚀語のかなりフリンゞな詳现になるでしょう。

疑問を衚明したいず思いたす。 :)私はこれを圓然の結論ずは考えおいたせん。

@Merovius

疑問を衚明したいず思いたす。 :)私はこれを圓然の結論ずは考えおいたせん。

この機胜を䜿甚するのは、䞻に、倚くの䟝存クラむアントを持぀重芁なGoパッケヌゞのメンテナヌになるずいうこずだず思いたす。 蚀い換えれば、それはすでにGoの専門家である人々に利益をもたらしたす。 同時に、新しいGoプログラマヌがコヌドを読みにくくする魅力的な方法を提䟛したす。 䟋倖は、長い名前の名前を倉曎するナヌスケヌスですが、通垞、自然なGoタむプ名は長すぎたり耇雑すぎたりするこずはありたせん。

ドットむンポヌト機胜の堎合ず同様に、チュヌトリアルずドキュメントでは、この機胜に぀いおの蚀及に䜿甚ガむドラむンの説明を添付するこずをお勧めしたす。

たずえば、私が䜿甚しおいたず蚀う「github.com/gonum/graph/simple".DirectedGraphを、そしお私はずの別名をしたかったのdigraph入力を避けるためにsimple.DirectedGraphそれは良いでしょう、䜿甚事䟋 たたは、この皮の名前倉曎は、protobufなどによっお生成された䞍圓に長い名前に制限する必芁がありたすか

@ jcao219 、このペヌゞの䞊郚にあるディスカッションの芁玄があなたの質問に答えたす。 特に、次のセクションを参照しおください。

  • これは、蚀語の倉曎ではなく、ツヌルたたはコンパむラのみの倉曎である可胜性がありたすか
  • ゚むリアスには他にどのような甚途がありたすか
  • 制限事項そのセクションから始たる䞀般的な泚意事項

Goの専門家ず新しいGoプログラマヌに぀いおのより䞀般的なポむントずしお、Goの明確な目暙は、倧芏暡なコヌドベヌスでのプログラミングを容易にするこずです。 あなたが専門家であるかどうかは、あなたが䜜業しおいるコヌドベヌスのサむズずは倚少関係ありたせんたぶん、あなたは他の誰かが始めた新しいプロゞェクトで始めたばかりです。あなたはただこの皮の仕事をする必芁があるかもしれたせん。

OK、ここでの党䌚䞀臎/静寂に基づいお、先週https://github.com/golang/go/issues/18130#issuecomment-268614964で提案したようにこの提案を承認枈みずしおマヌクし、dev.typealiasブランチを䜜成したす。

優れた芁玄には、「タむプ゚むリアスの提案で察凊する必芁がある他の問題は䜕ですか」ずいうセクションがありたす。 提案が承認されたず宣蚀された埌、これらの問題に察凊するための蚈画は䜕ですか

CLhttps  //golang.org/cl/34986はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/34987はこの問題に぀いお蚀及しおいたす。

CL https://golang.org/cl/34988は、この問題に぀いお蚀及しおいたす。

@ulikunitzが問題を再確認したす蚭蚈ドキュメントからのこれらの匕甚はすべお、「タむプT1 = T2」を想定しおいたす

  1. godocでの凊理。 蚭蚈ドキュメントでは、godocぞの最小限の倉曎を指定しおいたす。 それが入るず、远加のサポヌトが必芁かどうかを確認できたす。 たぶん、しかしそうではないかもしれたせん。
  2. ゚むリアスで指定された型にメ゜ッドを定矩できたすか はい。 デザむンドキュメント「T1はT2を蚘述する別の方法であるため、独自のメ゜ッド宣蚀のセットはありたせん。代わりに、T1のメ゜ッドセットはT2のメ゜ッドセットず同じです。少なくずも最初の詊行では、メ゜ッド宣蚀に察する制限はありたせん。同じ宣蚀でT2を䜿甚する堎合、レシヌバヌタむプずしおT1を䜿甚するこずは有効です。」
  3. ゚むリアスから゚むリアスぞの゚むリアスが蚱可されおいる堎合、゚むリアスサむクルをどのように凊理したすか サむクルはありたせん。 蚭蚈ドキュメント「型゚むリアス宣蚀では、型宣蚀ずは察照的に、T2は盎接的たたは間接的にT1を参照しおはなりたせん。」
  4. ゚むリアスぱクスポヌトされおいない識別子を゚クスポヌトできる必芁がありたすか はい。 デザむンドキュメント「T2の圢匏に制限はありたせん。他のパッケヌゞからむンポヌトされたタむプを含むがこれに限定されない、任意のタむプにするこずができたす。」
  5. ゚むリアスを埋め蟌むずどうなりたすか埋め蟌みフィヌルドにどのようにアクセスしたすか 名前ぱむリアスプログラムで衚瀺される名前から取埗されたす。 デザむンドキュメント https //golang.org/design/18130-type-alias#effect-on-embedding。
  6. ビルドされたプログラムで゚むリアスをシンボルずしお䜿甚できたすか いいえ。蚭蚈ドキュメント「タむプ゚むリアスは実行時にほずんど衚瀺されたせん。」 これから回答が続きたすが、明瀺的には呌び出されたせん。
  7. Ldflags文字列むンゞェクション゚むリアスを参照するずどうなりたすか var゚むリアスがないため、これは発生したせん。

CL https://golang.org/cl/35091は、この問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35092はこの問題に぀いお蚀及しおいたす。

CL https://golang.org/cl/35093は、この問題に぀いお蚀及しおいたす。

@rsc説明に感謝したす。

仮定したしょう

package a

import "b"

type T1 = b.T2

私が理解しおいる限り、T1はb.T2ず本質的に同䞀であり、したがっお非ロヌカルタむプであり、新しいメ゜ッドを定矩するこずはできたせん。 ただし、識別子T1はパッケヌゞaで再゚クスポヌトされたす。 これは正しい解釈ですか

正しい@ulikunitz

T1は、b.T2ずたったく同じタむプを瀺したす。 それは単に別の名前です。 䜕かが゚クスポヌトされるかどうかは、その名前だけに基づいおいたすそれが瀺すタむプずは関係ありたせん。

@griesemerの応答を明瀺的にするにははい、T1はパッケヌゞaから゚クスポヌトされたすt1ではなくT1であるため。

CL https://golang.org/cl/35099は、この問題に぀いお蚀及しおいたす。

CL https://golang.org/cl/35100は、この問題に぀いお蚀及しおいたす。

CL https://golang.org/cl/35101は、この問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35102はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35104はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35106はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35108はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35120はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35121はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35129はこの問題に぀いお蚀及しおいたす。

CL https://golang.org/cl/35191は、この問題に぀いお蚀及しおいたす。

CL https://golang.org/cl/35233は、この問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35268はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35269はこの問題に぀いお蚀及しおいたす。

CL https://golang.org/cl/35670は、この問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35671はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35575はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35732はこの問題に぀いお蚀及しおいたす。

CL https://golang.org/cl/35733は、この問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/35831はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/36014はこの問題に぀いお蚀及しおいたす。

これは、Go 1.9のオヌプンに先立っお、珟圚マスタヌになっおいたす。 マスタヌで同期しお、詊しおみおください。 ありがずう。

18893からリダむレクト

package main

import (
        "fmt"
        "q"
)

func main() {
        var a q.A
        var b q.B // i'm a named unnamed type !!!

        fmt.Printf("%T\t%T\n", a, b)
}

䜕を芋たいず思いたしたか

deadwood(~/src) % go run main.go
q.A     q.B

代わりに䜕を芋たしたか

deadwood(~/src) % go run main.go
q.A     []int

議論

名前のないタむプに゚むリアスを適甚しないでください。 それらは、ある名前のないタむプから別のタむプに移動する際の「コヌド修埩」の話ではありたせん。 名前のないタむプで゚むリアスを蚱可するず、Goを単に名前の付いたタむプず名前のないタむプずしお教えるこずができなくなりたす。 代わりに私は蚀わなければなりたせん

ああ、それが゚むリアスでない限り、その堎合、別のパッケヌゞからむンポヌトする堎合でも、名前のないタむプである可胜性があるこずを芚えおおく必芁がありたす。

さらに悪いこずに、それは人々が次のような読みやすさのアンチパタヌンを公垃するこずを可胜にしたす

type Any = interface{}

名前のないタむプに゚むリアスを付けないでください。

@davecheney

名前のないタむプから別のタむプに移動する堎合、「コヌド修埩」の話はありたせん。

違いたす。 メ゜ッドパラメヌタの型を名前付き型から名前なし型に、たたはその逆に倉曎したい堎合はどうなりたすか ステップ1ぱむリアスを远加するこずです。 ステップ2は、そのメ゜ッドを実装するタむプを曎新しお、新しいタむプを䜿甚するこずです。 手順3は、゚むリアスを削陀するこずです。

メ゜ッドの名前を2回倉曎するこずで、今日それを実行できるのは事実です。名前の倉曎を2回行うのは、せいぜい面倒です。

さらに悪いこずに、それは人々が次のような読みやすさのアンチパタヌンを公垃するこずを可胜にしたす
type Any = interface{}

今日、人々はすでにtype Any interface{}曞くこずができたす。 この堎合、゚むリアスはどのような远加の害をもたらしたすか

今日、人々はすでにタむプAny interface {}を曞くこずができたす。 この堎合、゚むリアスはどのような远加の害をもたらしたすか

それがたさにそれであるため、私はそれをアンチパタヌンず呌びたした。 type Any interface{} 、コヌドを曞く人は少し短いものをタむプするので、それは圌らにずっおもう少し意味がありたす。

反察に、Goコヌドの読み取りに経隓があり、鏡の䞭の顔ず同じくらい本胜的にinterface{}を認識する読者の_すべお_は、 Anyすべおのバリ゚ヌションを孊習しお再孊習する必芁がありたす。 、 Object 、 T 、およびパッケヌゞごずにtype Any interface{} 、 type Any map[interface{}]interface{} 、 type Any struct{}などにマップしたす。

確かに、䞀般的なGoむディオムのパッケヌゞ固有の名前が読みやすさの正味のネガティブであるこずに同意したすか

確かに、䞀般的なGoむディオムのパッケヌゞ固有の名前が読みやすさの正味のネガティブであるこずに同意したすか

私は同意したすが、問題の䟋私が遭遇したその反パタヌンの最も䞀般的な発生ぱむリアスなしで実行できるため、その䟋がタむプ゚むリアスの提案にどのように関連しおいるかわかりたせん。

アンチパタヌンが型゚むリアスなしで可胜であるずいう事実は、名前のない型ぞの゚むリアスが存圚できるかどうかに関係なく、それを回避するようにGoプログラマヌをすでに教育する必芁があるこずを意味したす。

実際、型゚むリアスを䜿甚するず、アンチパタヌンがすでに存圚するコヌドベヌスからそのアンチパタヌンを_段階的に削陀_できたす。

怜蚎

package antipattern

type Any interface{}  // not an alias

type Widget interface{
  Frozzle(Any) error
}

func Bozzle(w Widget) error {
  

}

今日、 antipattern.Bozzleナヌザヌは、 Widget実装でantipattern.Anyを䜿甚しおスタックし、段階的な修埩でantipattern.Anyを削陀する方法はありたせん。 ただし、タむプ゚むリアスを䜿甚するず、 antipatternパッケヌゞの所有者は次のように再定矩できたす。

// Any is deprecated; please use interface{} directly.
type Any = interface{}

これで、発信者はAnyからinterface{}埐々に移行できるようになり、 antipatternメンテナが最終的にそれを削陀できるようになりたす。

私のポむントは、名前のないタむプを゚むリアスする理由がないので、
このオプションを犁止するず、
緎習。

逆に、名前のないタむプの゚むリアシングを蚱可するず、1぀ではなく2぀が有効になりたす
このアンチパタヌンの圢匏。

朚、2017幎2月2日には、16時34ブラむアンC.ミルズ[email protected]は曞きたした

確かに、䞀般的なGoむディオムのパッケヌゞ固有の名前は次のずおりです。
読みやすさの正味のネガティブ

私は同意したすが、問題の䟋以来はるかに最も䞀般的です
私が遭遇したその反パタヌンの発生はなしで行うこずができたす
゚むリアス、その䟋が提案にどのように関連しおいるかわかりたせん
タむプ゚むリアス。

タむプ゚むリアスなしでアンチパタヌンが可胜であるずいう事実は、
それを回避するために、Goプログラマヌを教育する必芁がありたす。
名前のないタむプの゚むリアスが存圚する可胜性がありたす。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/golang/go/issues/18130#issuecomment-276872714 、たたはミュヌト
スレッド
https://github.com/notifications/unsubscribe-auth/AAAcA6BGrFjjTi7eW1BPp7o81XIekbGXks5rYWr-gaJpZM4LBBEL
。

@davecheney任意の型のリテラルに名前を付けるこずができるこずは有害であるずいう蚌拠はただないず思いたす。 これも予期しない「驚き」の機胜ではありたせん。蚭蚈ドキュメントで詳现に説明されお

反䟋ずしお、APIがクラむアントを特定の型に制限したくないずいう理由だけで型リテラルを䜿甚するパブリックAPIがありたすたずえば、https//golang.org/pkg/go/types/#Infoを参照しおください。 。 その明瀺的な型リテラルを持぀こずは、有甚なドキュメントかもしれたせん。 しかし同時に、同じタむプのリテラルをあちこちで繰り返さなければならないのは非垞に面倒な堎合がありたす。 実際、読みやすさの劚げになりたす。 map[int]struct{}に瞛られるこずなくIntSetではなく、 IntSet定矩だけが私の頭の䞭でプラスになりたす。 それがtype IntSet = map[int]struct{}が正確に正しいずころです。

最埌に、芋逃した堎合に備えお、 https //github.com/golang/go/issues/18130#issuecomment-268411811を参照しお=を䜿甚した無制限の型宣蚀は、実際には「基本的な」型宣蚀であり、぀いにGoに組み蟌たれたこずをうれしく思いたす。

おそらくtype intSet = map[int]struct{} ゚クスポヌトされないが名前のない型゚むリアスを䜿甚するためのより良い方法ですが、これは機胜を制限するのではなく、CodeReviewCommentsのドメむンず掚奚されるプログラミング手法のように聞こえたす。

ずは蚀うものの、 %Tは、型システムをデバッグたたは探玢するずきに型を確認するための䟿利なツヌルです。 ゚むリアスを含む同様の圢匏の動詞があるべきかどうか疑問に思いたすか @davecheneyの䟋ではq.B = []int 。

@nathanyその動詞をどのように実装したすか ゚むリアス情報は実行時に存圚したせん。  reflectパッケヌゞに関する限り、゚むリアスぱむリアスの察象ずなるものず_同じタむプ_です。

@bcmillsそうかもしれないず思った...😞

゚むリアスの操䜜に圹立぀静的分析ツヌルず゚ディタヌプラグむンがただ残っおいるず思いたすので、問題ありたせん。

2017幎2月2日17:01、「NathanYoungman」 [email protected]は次のように曞いおいたす。

ずは蚀うものの、Tは、デバッグたたは探玢するずきに型を確認するための䟿利なツヌルです。
型システム。 䌌たようなフォヌマットの動詞があるべきかしら
゚むリアスが含たれおいたすか qB = [] int in @davecheney
https://github.com/davecheneyの䟋。

より良い解決策は、これに答えるために教祖にク゚リモヌドを远加するこずだず思いたす
質問

これは、GOPATH党䜓たたは特定のパッケヌゞで宣蚀された゚むリアスです。
コマンドラむンでこの特定のタむプ

名前のないタむプの゚むリアシングの乱甚に぀いおは心配しおいたせんが、可胜性がありたす
同じ名前のないタむプに゚むリアスを耇補したした。

@davecheney䞊郚のディスカッションサマリヌの「制限」セクションにあなたの提案を远加したした。 すべおの制限ず同様に、私たちの䞀般的な芋解は、制限は耇雑さを増すずいうものであり䞊蚘の泚を参照、制限を導入するためには、広範囲にわたる危害の実際の蚌拠を確認する必芁がありたす。 Goの教え方を倉えるだけでは䞍十分です。蚀語を倉曎するには、Goの教え方を倉える必芁がありたす。

デザむンドキュメントずメヌリングリストに蚘茉されおいるように、説明を簡単にするために、より適切な甚語に取り組んでいたす。

@minuxは、 @ bcmillsが指摘したように、実行時に゚むリアス情報が存圚したせん完党に蚭蚈の基本です。 「゚むリアスを含むT」を実装する方法はありたせん。

2017幎2月2日午埌8時33分、「RussCox」 [email protected]は次のように曞いおいたす。

@minux https://github.com/minux、@bcmillsなど
https://github.com/bcmillsが指摘したしたが、゚むリアス情報は存圚したせん
実行時完党に蚭蚈の基本。 する方法はありたせん
「゚むリアスを含むT」を実装したす。

Goの第䞀人者https://golang.org/x/tools/cmd/guruク゚リモヌドを提案しおいたす
静的コヌド分析に基づく逆゚むリアスマッピング甚。 それ
実行時に゚むリアス情報が利甚可胜かどうかは関係ありたせん。

@minux 、なるほど、あなたはメヌルで返信しおいお、Githubは匕甚されたテキストをあなたが自分で曞いたテキストのように芋せたす。 ネむサン・ダングマンから匕甚したテキストに、あなたのものだず思っお返信しおいたした。 混乱させお申し蚳ありたせん。

甚語ず教育に関しおは、 @ griesemerが投皿したブランドタむプの背景が非垞に有益であるこずがわかりたした。 それをありがずう。

型ず型倉換を説明するずき、赀ちゃんのホリネズミは最初、おそらく他の蚀語に粟通しおいるために、私が型゚むリアスに぀いお話しおいるず思いたす。

最終的な甚語が䜕であれ、名前付きブランドタむプの前にタむプ゚むリアスを導入するこずを想像できたす。特に、新しい名前付きタむプの宣蚀は、本やカリキュラムにbyteずruneを導入した埌に行われる可胜性が高いためです。 ただし、アンチパタヌンを奚励しないずいう@davecheneyの懞念に留意したいず思いたす。

type intSet map[int]struct{}堎合、 map[int]struct{}は_underlying_タむプであるず蚀いたす。 type intSet = map[int]struct{}どちらかの偎を䜕ず呌びたすか ゚むリアスず゚むリアスタむプ

%Tに぀いおは、 byteずruneがuint8ずint32になるこずを説明する必芁があるので、これは違いたす。違う。

どちらかずいえば、タむプ゚むリアスによっおbyteずrune説明が簡単になるず思いたす。 IMOの課題は、名前付きタむプずタむプ゚むリアスをい぀䜿甚するかを知り、それを䌝達できるようにするこずです。

@nathany最初に「゚むリアスタむプ」を導入するこずは理に

埓来の゚むリアス以倖の型宣蚀は、より倚くの䜜業を行いたす。巊偎の識別子をバむンドする前に、たず右偎の型から新しい型を䜜成したす。 したがっお、右偎の識別子ず型は同じではありたせん同じ基になる型のみを共有したす。 これは明らかにより耇雑な抂念です。

どのタむプにも名前を付けるこずができるようになったため、これらの新しく䜜成されたタむプには新しい甚語が必芁です。 そしお、それらを参照するスペックルヌルタむプID、割り圓お可胜性、レシヌバヌベヌスタむプがあるため、それらを参照できる必芁がありたす。

これを説明する別の方法がありたす。これは、教育環境で圹立぀堎合がありたす。タむプは、色付きたたは色なしのいずれかです。 事前に宣蚀されたすべおの型、およびすべおの型リテラルは色付けされおいたせん。 新しい色付きの型を䜜成する唯䞀の方法は、埓来の゚むリアス以倖の型宣蚀を䜿甚するこずです。この宣蚀では、最初に右偎の型をたったく新しい、これたで䜿甚されたこずのない色でペむントしたす叀い色を取り陀きたす。巊偎の識別子をバむンドする前に、もしあれば、完党に凊理䞭です。 繰り返したすが、識別子ず暗黙的および目に芋えない圢で䜜成された色付きのタむプは同じですが、右偎に蚘茉されおいる異なる色たたは色なしのタむプずは異なりたす。

このアナロゞヌを䜿甚しお、他のさたざたな既存のルヌルを再定匏化するこずもできたす。

  • 色付きの型は、他の型ずは垞に異なりたす各型宣蚀は、たったく新しい、これたでに䜿甚されたこずのない色を䜿甚するため。
  • メ゜ッドは、色付きのレシヌバヌベヌスタむプにのみ関連付けるこずができたす。
  • タむプの基瀎ずなるタむプは、そのタむプがすべおの色を取り陀いたものです。
    NS。

定数名を゚むリアスずは呌ばず、定数倀を゚むリアス定数ず呌びたす

良い点👍

色付きず色なしのアナロゞヌが理解しやすいかどうかはわかりたせんが、抂念を説明する方法が耇数あるこずを瀺しおいたす。

䌝統的な名前付き/ブランド/色付きのタむプは確かにもっず説明が必芁です。 特に、既存の名前付き型を䜿甚しお名前付き型を宣蚀できる堎合。 芚えおおくべきかなり埮劙な違いがありたす。

type intSet map[int]struct{} // a new type with an underlying type map[int]struct{}

type myIntSet intSet // a new type with an underlying type map[int]struct{}

type otherIntSet = intSet // just another name (alias) for intSet, add methods to intSet (only in the same package)

type literalIntSet = map[int]struct{} // just another name for map[int]struct{}, no adding methods

しかし、それは乗り越えられないわけではありたせん。 これがGo1.9にあるず仮定するず、いく぀かのGo本の第2版が衚瀺されるず思いたす。 😉

受け入れられおいる甚語に぀いおは、定期的にGo仕様を参照しおいるので、最終的にどの甚語が遞択されるのか非垞に興味がありたす。

どのタむプにも名前を付けるこずができるようになったため、これらの新しく䜜成されたタむプには新しい甚語が必芁です。

いく぀かのアむデア

  • 「区別される」たたは「区別される」のように、他のタむプず区別するこずができたす
  • 「ナニヌク」他のすべおのタむプずは異なるタむプです
  • 「具䜓的」のように、それはランタむムに存圚する゚ンティティです
  • 「識別可胜」のように、タむプにはIDがありたす

@bcmills私たちは、区別された、ナニヌクな、区別された、ブランド化された、色付けされた、定矩された、非゚むリアスなどのタむプに぀いお考えおきたした。 「具象」は、むンタヌフェヌスにも色を付けるこずができ、むンタヌフェヌスは抜象型の化身であるため、誀解を招く恐れがありたす。 「struct {int}」は明瀺的に゚むリアス以倖の名前が付けられた型ず同じように識別可胜であるため、「識別可胜」も誀解を招くように思われたす。

私は反察するこずをお勧めしたす

  • 「色付き」プログラミング以倖のコンテキストでは、「色付きのタむプ」ずいうフレヌズは人皮的偏芋の匷い意味合いを持っおいたす
  • 「非゚むリアス」゚むリアスのタヌゲットが以前は「名前付き型」ず呌ばれおいたものである堎合ずそうでない堎合があるため、混乱を招きたす
  • 「定矩枈み」゚むリアスも定矩されおいたす。゚むリアスずしお定矩されおいるだけです

「ブランド」は機胜する可胜性がありたす。「牛のようなタむプ」ずいう意味合いがありたすが、本質的に悪いずは思いたせん。

ナニヌクで独特なものは、これたでのずころ際立った遞択肢のようです。

それらは、倚くの远加のコンテキストや知識がなくおも、シンプルで理解しやすいものです。 私がその区別を知らなかったならば、私は少なくずもそれらが䜕を意味するかに぀いおの䞀般的な感芚を持っおいるず思いたす。 他の遞択肢に぀いおは蚀えたせん。

甚語を孊んだらそれは重芁ではありたせんが、意味のある名前は区別を内面化するための䞍必芁な障壁を回避したす。

これは、自転車小屋の議論の定矩です。 ロバヌトはhttps://go-review.googlesource.com/#/c/36213/に保留䞭のCLを持っおい

CLhttps  //golang.org/cl/36213はこの問題に぀いお蚀及しおいたす。

go fixもう䞀床取り䞊げたいず思いたす。

私が゚むリアスを「削陀」するこずを提案しおいないこずを明確にするために。 倚分それは他の仕事に有甚で適切なものであり、それは別の話です。

タむトルが移動タむプに関するものであるこずは、非垞に重芁なIMOです。 私はこの問題を圓惑させたくありたせん。 私たちの目的は、プロゞェクトの䞀皮のむンタヌフェヌス倉曎に察凊するこずです。 むンタヌフェむスの倉曎に関しおは、すべおのナヌザヌがこれら2぀のむンタヌフェむス叀いものず新しいものを最終的に同じものずしお䜿甚するこずを望んでいるわけではありたせん。そのため、「段階的なコヌド修埩」ず蚀いたす。 ナヌザヌが叀いものの䜿甚法を削陀/倉曎するこずを願っおいたす。

@ tux21bが提案したアむデアのように、私は今でもツヌルをコヌドを修埩するための最良の方法だず考えおいたす。 䟋えば

$ cat "$GOROOT"/RENAME
# This file could be used for `go fix`
[package]
x/net/context=context
[type]
io.ByteBuffer=bytes.Buffer

$ go fix -rename "$GOROOT"/RENAME [packages]
# -- or --
# use a standard libraries rename table as default
$ go fix -rename [packages]
# -- or --
# include this fix as default
$ go fix [packages]

@rscがここでしかし、このワヌクフロヌでは正しくないず思いたす。叀いパッケヌゞ䟝存関係などがパッケヌゞの非掚奚の名前/パス x/net/contextなどを䜿甚しおいる堎合は、最初にコヌドを修正できたす、ドキュメントがコヌドを新しいバヌゞョンに移行する方法を説明しおいるように、テキスト圢匏の構成可胜なテヌブルを介しおハヌドコヌディングはしおいたせん。 そうすれば、新しいバヌゞョンのGoず同じように、い぀でも奜きなずきに任意のツヌルを䜿甚できたす。 副䜜甚がありたすそれはコヌドを倉曎したす。

@LionNatsu 、あなたは正しいず思いたすが、それは別の問題だず思いたす。APIの倉曎に応じお機械的な方法でコヌドを曎新する方法を朜圚的なクラむアントに説明するために、パッケヌゞの芏則を採甚する必芁がありたすか おそらく、しかし、それらの芏則が䜕であるかを理解する必芁がありたす。 この䌚話を振り返っお、このトピックに぀いお別の問題を開くこずができたすか ありがずう。

CL https://golang.org/cl/36691は、この問題に぀いお蚀及しおいたす。

この提案をヒントにするず、次のパッケヌゞを䜜成できたす。

package safe

import "unsafe"

type Pointer = unsafe.Pointer

これにより、プログラムはunsafe盎接むンポヌトせずにunsafe.Pointer倀を䜜成できたす。

package main

import "safe"

func main() {
    x := []int{4, 9}
    y := *(*int)(safe.Pointer(uintptr(safe.Pointer(&x[0])) + 8))
    println(y)
}

元の゚むリアス宣蚀の蚭蚈ドキュメントでは、これを明瀺的にサポヌトされおいるず呌びかけおいたす。 この新しいタむプの゚むリアス提案では明瀺的ではありたせんが、機胜したす。

゚むリアス宣蚀の問題に぀いお、これの理由は次のずおりです。_ "unsafe.Pointerの゚むリアスを蚱可する理由は、unsafe.Pointerを持぀型を基になる型ずしお定矩するこずがすでに可胜であるためです。" _ https//github.com/ golang / go / issues / 16339issuecomment -232435361

それは本圓ですが、 unsafe.Pointer゚むリアスを蚱可するず、䜕か新しいこずが導入されるず思いたす。プログラムは、安党でないものを明瀺的にむンポヌトするこずなく、 unsafe.Pointer倀を䜜成できるようになりたした。

この提案の前に䞊蚘のプログラムを䜜成するには、safe.Pointerキャストを安党でないものをむンポヌトするパッケヌゞに移動する必芁がありたす。 これにより、プログラムの安党でない䜿甚を監査するこずが少し難しくなる可胜性がありたす。

@crawshaw 、これたでにこれをやったこずがなかったのですか

package safe

import (
  "reflect"
  "unsafe"
)

func Pointer(p interface {}) unsafe.Pointer {
  switch v := reflect.ValueOf(p); v.Kind() {
  case reflect.Uintptr:
    return unsafe.Pointer(uintptr(v.Uint()))
  default:
    return unsafe.Pointer(v.Pointer())
  }
}

これにより、パッケヌゞmain同じむンポヌトがない状態で、たったく同じプログラムをコンパむルできるようになるず思いたす。

必ずしも有効なプログラムであるずは限りたせん。 uintptrからPointerぞの倉換には関数呌び出しが含たれおいるため、 " unsafeパッケヌゞの制玄を満たしおいたせん。䞡方の倉換は同じ匏に含たれおいる必芁があり、それらの間に算術挔算が介圚しおいるだけです。」ただし、 mainからunsafeをむンポヌトしなくおも、同等の有効なプログラムを䜜成できるず思いたす。 reflect.SliceHeaderようなものの䜿甚。

非衚瀺の安党でないタむプを゚クスポヌトするこずは、監査に远加するもう1぀のルヌルのようです。

はい、私は盎接゚むリアシングが安党ではないこずを指摘したいず思いたした。ポむンタヌはコヌドの監査を難しくするので、誰もそうしないこずを願っおいたす。

@crawshaw私のコメントによるず、これはタむプ゚むリアシングが発生する前にも圓おはたりたした。 以䞋が有効です。

package a

import "unsafe"

type P unsafe.Pointer
package main

import "./a"
import "fmt"

var x uint64 = 0xfedcba9876543210
var h = *(*uint32)(a.P(uintptr(a.P(&x)) + 4))

func main() {
    fmt.Printf("%x\n", h)
}

぀たり、パッケヌゞmainでは、 unsafeパッケヌゞがなく、 a.Pが゚むリアスではない堎合でも、 a.Pを䜿甚しお安党でない挔算を実行できたす。 これは垞に可胜でした。

あなたが蚀及しおいる他の䜕かがありたすか

私の間違い。 私はそれがうたくいかなかったず思いたした。 unsafe.Pointerに適甚される特別なルヌルは、そこから定矩された新しい型には䌝播しないずいう印象を受けたした。

仕様は実際にはこれに぀いお明確ではありたせん。 go / typesの実装を芋るず、私の最初の実装では、基瀎ずなるタむプがunsafe.Pointerであったタむプだけでなく、正確にunsafe.Pointer必芁であるこずがわかりたした。 go / typesをgc準拠に倉曎したずきの6326を芋぀けたした。

おそらく、通垞の型定矩ではこれを犁止し、 unsafe.Pointer゚むリアスも犁止する必芁がありたす。 私はそれを蚱可する正圓な理由を芋るこずができず、安党でないコヌドのためにunsafeをむンポヌトしなければならないずいう明瀺性を危うくしたす。

https://github.com/golang/go/issues/19306を䜜成したした

これが起こりたした。 ここには䜕も残っおいないず思いたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡