18

私は Go の初心者ですが、Go の常連はパラメトリック ポリモーフィズムを見逃していないことを読みました。新しい言語を学ぼうとするたびに、L99 の問題リストを使って練習します。

最初の問題 (Go では、スライスの最後の要素を取得する単一のステートメントになります) と同じくらい些細なことを書こうとしても、これを任意の型のスライスを取得する関数としてどのように記述し、(を使用して)上記で参照したその単一のステートメント) は、そのスライスの最後の要素を返しますか?

この言語にはパラメトリック ポリモーフィズムがありませんが、Go の常連がパラメトリック ポリモーフィズムを見逃していないと主張するには、これを行う慣用的な「Go」の方法が必要であると考えました。それ以外の場合、たとえばリストの最後の要素よりも例が複雑な場合は、すべてのタイプに対してタスクを実行する関数が必要になります。

私は何が欠けていますか?

4

4 に答える 4

13

あなたは「99 Lisp問題」を挙げていますが、Lispにはパラメトリックなポリモーフィズムや静的型がまったくありません。

Objective-C やジェネリックより前の Java などの多くの静的型付け言語には、パラメトリック ポリモーフィズムがありません。解決策は、Go では であるすべての値を受け入れることができる型を使用し、interface{}特定の型を取得する必要があるときにキャストすることです。

特定の質問については、「任意のタイプのスライス」を取る方法。残念ながら、スライスにはメソッドがないため、特にスライスを含むインターフェイスはありません。の使用に行き詰まるでしょうinterface{}。不明なスライス タイプがあるため、リフレクション (reflectパッケージ) を使用して、長さと容量の取得、追加、特定のインデックスでの要素へのアクセスなど、すべてのスライス操作を実行する必要があります。

もう 1 つの方法は、「任意のタイプのスライス」を使用する代わりに、「インターフェイス {} のスライス」を使用することです。つまり[]interface{}、すべてのコードで、通常のスライス演算子を使用でき、任意の要素を配置できますが、出たらキャスト。

于 2011-10-18T01:38:42.107 に答える
8

スライスの最後の要素を返す方法の Go の方法は、式としてインラインで単純に記述することです。例えば:

var a []int
...
last := a[len(a)-1]

a[len(a)-1]単純な式をジェネリック関数にカプセル化することは、不要な複雑さです。

Lisp とは異なり、Go は純粋に関数型の言語ではありません。99 個の Lisp 問題のリストに基づいて Go を評価することは、だまされている可能性があります。Go は「システム プログラミング言語」です。リスト操作、メタプログラミング、シンボリック AI、またはその他の Lisp に適したタスクは、Go の長所ではありません。

私は Go を、ガベージ コレクションと同時実行性を備えた改良された C と見なしています。Go は Lisp と競合するためにここにいるわけではありません。

于 2011-10-18T16:32:33.877 に答える
0

配列の最後の (および最初の) 要素を取得する方法の質問に答えるだけで、これが Go での適切な方法です。

last := a[:1] first := a[1:]

しかし、これはパラメトリック ポリモーフィズムとは何の関係もありません。つまり、型推論であり、コンパイル時に計算されます。

私はバイナリ ツリー ライブラリを作成しようとしていますが、データ型を抽象化するための最も効率的で読みやすく、パフォーマンスの高い方法にまだ苦労しています。具体的には、ストア、カーソル、およびインデックス マップ システムを作成しました。 walk 関数ですが、ノードに実際に格納されているデータ型を切り替えられるようにしたいと考えています。構成とプロセスへの埋め込みについて多くのことを学びましたが、完全に満足しているわけではありません。

私は関数型プログラミングの原理を少し知っています.Goはたまたま関数をファーストクラスとして扱うので、理論的にはおそらくパラメトリックポリモーフィズムの問題に対する機能的な解決策があるでしょう. 基本的に私は関数型パラダイムが大好きですが、とにかく再帰が嫌いなので、それを理解する過程にあります(私は反復を好み、視覚化するのが100倍簡単です)。

于 2018-04-22T10:38:44.700 に答える