25

ウィキペディアはダックタイピングについて次のように述べていました:

オブジェクト指向プログラミング言語を使用したコンピューター プログラミングでは、ダック タイピングは動的型付けのスタイルであり、特定のクラスからの継承や特定のインターフェイスの実装ではなく、オブジェクトの現在のメソッドとプロパティのセットによって有効なセマンティクスが決定されます。

(* 編集者注: この質問が投稿されて以来、ウィキペディアの記事は編集され、「動的」という単語が削除されました。)

構造型付けについて次のように述べています。

構造型システム (またはプロパティ ベースの型システム) は、型システムの主要なクラスであり、型の互換性と等価性は、明示的な宣言ではなく、型の構造によって決定されます。

次のように、構造的サブタイピングとダックタイピングを対比します。

[構造システム] は、実行時にアクセスされる構造の一部のみが互換性をチェックされる ... ダック タイピングとは対照的です。

しかし、ダックタイピングという用語は、少なくとも構造的なサブタイピングシステムを直感的に包含しているように思えます。実際、ウィキペディアには次のように書かれています。

概念の名前 [ダックタイピング] は、ジェームズ ウィットコム ライリーによるアヒル テストを指し、次のように表現できます。「アヒルのように歩き、アヒルのように泳ぎ、アヒルのように鳴く鳥を見たとき私はその鳥をアヒルと呼んでいます。」

だから私の質問は: 構造的サブタイピングをダックタイピングと呼べないのはなぜですか? ダック型として分類できない動的型付け言語も存在しますか?

追記:

reddit.com でdaydreamdrunkという名前の誰かが雄弁に言ったように、「アヒルのようにコンパイルし、アヒルのようにリンクするなら...」

あとがき

多くの答えは、基本的に、ここで既に引用したことを再ハッシュしているだけのようで、より深い質問に対処していません。動的型付けと構造的サブタイピングの両方をカバーするためにダックタイピングという用語を使用しないのはなぜですか? 構造的なサブタイピングではなく、ダックタイピングについてのみ話したい場合は、動的メンバー検索と呼んでください。私の問題は、ダックタイピングという用語について何も言わないことです。これは動的言語にのみ適用されます。

4

8 に答える 8

29

C++ と D のテンプレートは、動的ではないダック タイピングの完璧な例です。それは間違いなく:

特定のクラスからの継承や特定のインターフェイスの実装ではなく、オブジェクトの現在のメソッドとプロパティのセットが有効なセマンティクスを決定する型付け。

テンプレートをインスタンス化するために型が継承する必要があるインターフェイスを明示的に指定しません。テンプレート定義内で使用されるすべての機能が必要です。ただし、すべてがコンパイル時に解決され、生の不可解な 16 進数にコンパイルされます。私はこれを「コンパイル時のダックタイピング」と呼んでいます。私は、暗黙的なテンプレートのインスタンス化はコンパイル時のダックタイピングであり、最も過小評価されている機能の 1 つであるという考え方から、ライブラリ全体を作成しました。

于 2009-12-22T18:31:58.383 に答える
15

構造型システム

構造型システムは、ある型全体を別の型全体と比較して、互換性があるかどうかを判断します。2 つの型ABが互換性をA持つBためには、同じ構造を持っている必要があります。つまり、 onと onのすべてのメソッドが同じシグネチャを持っている必要があります。AB

ダックタイピング

ダックタイピングでは、2 つのタイプが両方ともそのタスクを処理できる場合、そのタスクに対して同等であると見なされます。と ファイルに書き込みたいコードの一部に相当するA2つのタイプの場合、両方とも書き込みメソッドを実装する必要があります。BAB

概要

構造型システムは、すべてのメソッド シグネチャ (構造全体) を比較します。ダックタイピングは、特定のタスクに関連するメソッド (タスクに関連する構造) を比較します。

于 2009-12-22T18:19:25.473 に答える
11

ダックタイピングとは、ぴったり合うなら大丈夫という意味です

これは、動的に型付けされた両方に適用されます

def foo obj
    obj.quak()
end

または静的に型付けされ、コンパイルされた言語

template <typename T>
void foo(T& obj) {
    obj.quak();
}

重要なのは、どちらの例でも、指定されたタイプに関する情報がないということです。使用すると(実行時またはコンパイル時のいずれかで!)、型がチェックされ、すべての要件が満たされている場合、コードは機能します。値は、宣言の時点で明示的なタイプを持っていません。

構造型の型付けは、通常どおり、値を明示的に型付けすることに依存します-違いは、具体的な型が継承ではなく、その構造によって識別されることです。

上記の例の構造的に型付けされたコード(Scalaスタイル)は次のようになります

def foo(obj : { def quak() : Unit }) {
    obj.quak()
}

これを、OCamlのような構造的に型付けされた言語が、型を明示的に定義することを防ぐために型推論と組み合わせているという事実と混同しないでください。

于 2009-12-22T18:59:29.657 に答える
6

あなたの質問に本当に答えているかどうかはわかりませんが...

テンプレート化された C++ コードは、ダックタイピングに非常によく似ていますが、静的で、コンパイル時の構造的なコードです。

template<typename T>
struct Test
{
    void op(T& t)
    {
        t.set(t.get() + t.alpha() - t.omega(t, t.inverse()));
    }
};
于 2009-12-22T18:05:42.073 に答える
5

構造的型付けは型推論などによって型情報を決定するために使用される (Haskell や OCaml を考えてください) のに対し、ダック型付けは「型」自体を気にせず、特定のメソッド呼び出しを処理できるということだけを理解しています。プロパティ アクセスなど ( respond_to?Ruby で考えるか、Javascript で機能チェックを行うか)。

于 2009-12-22T18:04:38.893 に答える
5

さまざまな用語の定義に違反するいくつかのプログラミング言語の例が常に存在します。たとえば、ActionScript は、技術的に動的ではないインスタンスでのダックタイピング スタイルのプログラミングをサポートしています。

var x:Object = new SomeClass();
if ("begin" in x) {
    x.begin();
}

この場合、"x" のオブジェクト インスタンスに "begin" メソッドがあるかどうかをテストしてから、インターフェイスを使用する代わりに呼び出しました。クラス SomeClass() 自体が動的ではない場合でも、これは ActionScript で機能し、ほとんどダックタイピングです。

于 2009-12-22T18:10:25.817 に答える
4

動的ダックタイピングと同様の静的型付けコード (つまり C++) の動作が異なる状況があります。

template <typename T>
void foo(T& obj) {
    if(obj.isAlive()) {
        obj.quak();
    }
}

C++ では、コードをコンパイルするには、オブジェクトに メソッドisAliveとメソッドの両方が必要です。quak動的型付け言語の同等のコードの場合、オブジェクトは true を返すquak場合にのみメソッドを持つ必要があります。isAlive()私はこれを構造 (構造型付け) と動作 (ダック型付け) の違いと解釈しています。

(ただし、ウィキペディアの「ダックタイピングは動的でなければならない」を額面どおりに解釈し、それを理解できるようにすることで、この解釈に到達しました。暗黙の構造的タイピングがダックタイピングであるという別の解釈も一貫しています。)

于 2014-04-17T16:19:08.030 に答える
2

私は「ダックタイピング」をプログラミング スタイルとして捉えていますが、「構造型タイピング」は型システムの機能です。

構造型付けとは、特定の構造的プロパティを持つすべての値を含む型を表現する型システムの機能を指します。

ダックタイピングとは、他の制約を課すことなく、実際に目の前の仕事に必要な、渡された値の機能のみを使用するコードを書くことを指します。

したがって、「ダック型」を構造型として正式に宣言することで、構造型を使用してダック タイピング スタイルでコーディングできます。しかし、「ダックタイピング」をせずに構造型を使用することもできました。たとえば、共通の構造型を宣言して名前を付け、それをどこでも使用することにより、関連する関数/メソッド/プロシージャ/述語/クラス/その他の束へのインターフェイスを記述した場合、一部のコードユニットが必要ない可能性が非常に高くなります構造型のすべての機能があるため、理論的に正しく機能する可能性のある値を拒否するように、それらの一部を不必要に制約しました。

したがって、共通点があることはわかりますが、ダックタイピングが構造型タイピングを包含するとは思いません。私の考えでは、ダックタイピングは構造型タイピングを包含できたものでさえありません。それらは同じ種類のものではないからです。動的言語でのダックタイピングを単に「暗黙的でチェックされていない構造型」と考えると、何かが欠けています。ダックタイピングは、プログラミング言語の単なる技術的な機能ではなく、使用するかどうかを選択するコーディング スタイルです。

たとえばisinstance、Python でチェックを使用して、オブジェクト指向スタイルの「クラスまたはサブクラス」型の制約を偽造することができます。特定の属性とメソッドをチェックして、構造型の制約を偽造することもできます (外部関数にチェックを入れて、名前付きの構造型を効果的に取得することもできます!)。私は、これらのオプションのどちらもダックタイピングを例示していないと主張します (構造型が非常にきめ細かく、それらをチェックするコードと密接に同期していない限り)。

于 2014-04-24T01:35:44.310 に答える