問題タブ [go-interface]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
oop - 型階層の言語サポートなしで関連するものの階層をモデル化する
私は Go を初めて使用します。最初にやりたいことの 1 つは、小さなマークアップ ページ生成ライブラリを Go に移植することです。主な実装は Ruby であり、その設計は非常に「古典的なオブジェクト指向」です (少なくとも、アマチュア プログラマーの観点から OO を理解している限り)。これは、マークアップされたドキュメント タイプ間の関係をどのように見るかをモデル化したものです。
小さなプロジェクトの場合、次のようなことをするかもしれません (現在必要な Go に変換されます)。
大規模なプロジェクトの場合、たとえば「Egg Sample」という Web サイトの場合、既存のページ タイプの 1 つをサブクラス化し、より深い階層を作成します。
これは、従来のオブジェクト指向設計にうまく適合します。サブクラスは無料で多くのものを取得し、親クラスとは異なるいくつかの部分にのみ焦点を当てています。たとえば、EggSamplePage は、すべての Egg Sample ページに共通するいくつかのメニューとフッターを追加できます。
ただし、Go には型の階層という概念がありません。クラスはなく、型の継承もありません。メソッドの動的なディスパッチもありません(これは上記から続くようです; Go 型HtmlPage
は Go 型の「種類」ではありませんPage
)。
Go は以下を提供します。
- 埋め込み
- インターフェース
これらの 2 つのツールは、私が望むものを得るのに十分なはずですが、何度か間違ったスタートを切った後、私は困惑し、イライラしています。私の推測では、私はそれについて間違って考えていると思います.誰かがこれを行う方法について正しい方向に私を向けることができることを望んでいます.
これは私が抱えている特定の実際の問題です。そのため、より広範な質問に対処せずに特定の問題を解決するための提案を歓迎します。しかし、それを回避するものではなく、「構造体、埋め込み、インターフェイスをこのように組み合わせることで、簡単に思い通りの動作を実現できる」という形で答えてくれることを願っています。古典的なオブジェクト指向言語から Go に移行する多くの新参者は、同様の混乱の時期を経験する可能性が高いと思います。
通常、壊れたコードをここに表示しますが、いくつかのバージョンがあり、それぞれに問題があります。それらを含めることで、すでにかなり長くなった私の質問が実際に明確になるとは思いません。もちろん、有用であることが判明した場合は、コードを追加します。
私がやったこと:
- The Go FAQ の多くを読む(特に関連があると思われる部分)
- Effective Goの多くを読む(特に関連があると思われる部分)
- 多くの検索語の組み合わせで Google を検索した
- golang-nutに関するさまざまな投稿を読む
- 非常に不適切な Go コードが書かれている
- Go標準ライブラリのソースコードを調べて、似ていると思われる例を探しました
私が探しているものについてもう少し明確にするために:
このような階層を扱う慣用的なGoの方法を学びたいです。私のより効果的な試みの 1 つは、Go らしくないようです。
これは私を近づけましたが、完全ではありませんでした。現時点で私が言いたいのは、このような状況で Go プログラマーが使用するイディオムを学ぶのは失敗した機会のように思えるということです。
私は合理的である限りDRY(「Don't Repeat Yourself」)になりたいです。
text/template
各テンプレートの多くが他のテンプレートと同一である場合、ページの種類ごとに個別に作成する必要はありません。私の破棄された実装の 1 つはこのように動作しますが、上で概説したようにページ タイプのより複雑な階層を取得すると、管理できなくなるようです。html5Page
サポートするタイプ (や などxhtmlPage
) にそのまま使用でき、ライブラリを直接コピーして編集することなく、上記のように拡張できるコア ライブラリ パッケージを用意したいと考えています。(従来の OO では、たとえば、Html5Page を拡張/サブクラス化し、いくつかの微調整を行います。) 現在の試みは、これにはあまり適していないようです。
これについてのGoの考え方を説明するために、正しい答えは多くのコードを必要としないと思います。
更新:これまでのコメントと回答に基づいて、私はそれほど遠くないようです。私の問題は、私が思っていたよりも一般的なデザイン指向ではなく、私が物事をどのように行っているかについてもう少し正確に書かれているに違いありません。だからここに私が取り組んでいるものがあります:
これは機能しますが、いくつかの問題があります。
- それは本当に厄介な感じです
- 私は自分自身を繰り返しています
- それは不可能かもしれませんが、理想的には、すべての Page タイプに
String()
、関数を使用するのではなく、正しいことを行うメソッドが必要です。
私は何か間違ったことをしていて、これを改善できるGoのイディオムがあるのではないかと強く疑っています。
正しいことをするString()
メソッドが欲しいのですが、
は、 を介して使用された場合でも、常にpage
メソッドを使用HtmlPage
します。これは、インターフェイス以外では動的ディスパッチが不足しているためです。
私の現在のインターフェースベースのページ生成では、fmt.Println(p)
(どこp
にある種のページがあるのか) を行うだけでなく、 と の間で具体的に選択する必要がfmt.Println(dsts.PageString(p))
ありfmt.Println(dsts.HtmlPageString(p))
ます。それは非常に間違っていると感じます。
PageString()
そして、 /HtmlPageString()
とheaderString()
/の間でぎこちなくコードを複製していますhtmlHeaderString()
。
ですから、Go ではなく Ruby や Java で考え続けている結果として、まだ設計上の問題に苦しんでいるように感じます。私が説明したクライアント インターフェイスのようなものを備えたライブラリを構築するための、簡単で慣用的な Go の方法があることを願っています。
go - インターフェイスのスライスを型変換する
[]T
Go が に暗黙的に変換される[]interface{}
ときに、なぜ Go が暗黙的に に変換されないのか興味がT
ありinterface{}
ます。この変換について、私が見逃している重要なことはありますか?
例:
go build
文句を言う
関数の引数で (type []string) を type []interface {} として使用することはできません
そして、私が明示的にそれをやろうとすると、同じこと:b := []interface{}(a)
文句を言う
(type []string) を type []interface {} に変換できません
したがって、この変換を行う必要があるたびに (これは頻繁に発生するようです)、次のようなことを行ってきました。
これを行うためのより良い方法、またはこれらの変換を支援する標準ライブラリ関数はありますか? int や文字列などのリストを取得できる関数を呼び出すたびに、4 行の余分なコードを記述するのはばかげているように思えます。
interface - インターフェイスを理解する
私はGolangの初心者です。簡単なコードを記述して、GoInterfaceを理解しようとしていました。インターフェイスメソッドを参照する正しい方法を理解できないため、エラーが発生します。どこが間違っているのか教えてください。
t.Noofchar()でメソッドを正しく参照していますか?または私が見逃している何か他のものがあります
interface - 依存関係を簡素化する Golang インターフェイス?
うーん、私はインターフェイスに頭を悩ませています。
だから私はmongodbのものを処理するためにGoパッケージを使用していますが、そのパッケージをすべてのモデルにインポートしたくありません。サブパッケージ (モデルなど) の多くを標準ライブラリだけに保持したいと考えています。だから私はいくつかのインターフェースを次のようにレイアウトすると思った:
問題は、次のような関数を使用するときです。
これは、mgo.Database を渡すことによって、インターフェイスを使用しているパッケージに含まれています。
コンパイラ エラーが発生します。
controllers/handlers.go:35: ctx.Database (タイプ *mgo.Database) を関数引数のタイプ dota.database として使用することはできません: *mgo.Database は dota.database を実装していません (C メソッドの間違ったタイプ) have C(string) ) *mgo.Collection が欲しい C(文字列) dota.collection
この概念について何が欠けていますか?
constructor - インターフェイスのコンストラクター メソッド? (ゴラン語で)
次のインターフェースと構造体がある場合:
New()
次に、メソッドを (コンストラクターとして) インターフェイスに追加するにはどうすればよいShape
ですか?
ユースケースは、別の構造体がある場合ですSquare
次に、Square
メソッドがありArea()
ます。しかし、それはありませんNew()
。私の目的は、継承する構造体に自動的にメソッドをShape
持たせることです。New()
どうやってやるの?
go - インターフェイスから構造体へのポインタを取得しますか?
インターフェイスが与えられた場合、基になる値へのポインターを取得するにはどうすればよいですか?
私の素朴な試みは、次のような型アサーションを使用することでした:
しかし、私は得る:
go - インターフェイス値からの基になるポインター型
インターフェイスから基になるポインター型を取得するにはどうすればよいですか?