これらの用語がプログラミングのいたるところで使われているのを目にしますが、それらが何を意味するのか漠然とした考えを持っています。検索すると、実際にスタックオーバーフロー全体でそのようなことが尋ねられていることがわかります。私の知る限り、言語の静的/動的型付けは、強い/弱い型付けとは微妙に異なりますが、その違いが何であるかはわかりません。情報源が異なれば、異なる意味を使用しているようであり、用語を同じ意味で使用しているようです. 両方について話し、実際に違いを説明している場所を見つけることができません。誰かが私と他の世界のためにここでこれを明確に説明してくれたらいいのですが.
10 に答える
静的/動的型付けは、型情報がいつ取得されるか (コンパイル時または実行時) に関するものです。
強い/弱い型付けは、型がどの程度厳密に区別されるかに関するものです (たとえば、言語が文字列から数値への暗黙的な変換を試みるかどうか)。
詳細については、wiki ページを参照してください。
あなたは、アマチュアがプログラミング言語について話すために使用する用語の弱点を発見しました。 「強い」および「弱い」タイピングという用語は使用しないでください。技術的な意味について普遍的に合意されたものではないからです。対照的に、静的型付けは、プログラムが実行される前にチェックされることを意味し、プログラムは開始前に拒否される可能性があります。 動的型付けとは、実行中に値の型がチェックされることを意味し、型付けが不適切な操作により、プログラムが停止したり、実行時にエラーが発生したりする可能性があります。静的型付けの主な理由は、そのような「動的型エラー」を持つ可能性のあるプログラムを除外することです。
強い型付けは一般に、型システムに抜け穴がないことを意味しますが、弱い型付けは型システムを覆すことができることを意味します (保証を無効にします)。これらの用語は、静的型付けと動的型付けを意味するために誤って使用されることがよくあります。違いを理解するために、C について考えてみてください。この言語はコンパイル時に型チェック (静的型付け) が行われますが、多くの抜け穴があります。任意の型の値を同じサイズの別の型にほとんどキャストできます。特に、ポインター型は自由にキャストできます。Pascal は厳密に型付けされることを意図した言語でしたが、タグのないバリアント レコードという予期しない抜け穴があったことで有名です。
厳密に型指定された言語の実装は、多くの場合、時間の経過とともに抜け穴を獲得します。これは通常、ランタイム システムの一部を高水準言語で実装できるようにするためです。たとえば、Objective Caml には、Obj.magic
単純に引数を返すという実行時効果を持つ呼び出される関数がありますが、コンパイル時には、任意の型の値を別の型の値に変換します。私のお気に入りの例は Modula-3 で、その設計者は型キャスト構造を と呼びましたLOOPHOLE
。
とはいえ、「強い」と「弱い」という言葉をまったく同じように使っている人は一人もいません。だからそれらを避けてください。
簡単に言えば、静的に型付けされた言語では、型はstaticです。つまり、変数を型に設定すると、それを変更することはできません。これは、入力が参照する値ではなく、変数に関連付けられているためです。
たとえば、Java では次のようになります。
String str = "Hello"; //statically typed as string
str = 5; //would throw an error since java is statically typed
一方、動的に型付けされた言語では、型はdynamicです。つまり、変数を型に設定した後、それを変更できます。これは、入力が変数ではなく値に関連付けられているためです。
たとえば、Python では次のようになります。
str = "Hello" # it is a string
str = 5 # now it is an integer; perfectly OK
一方、言語の強い/弱い型付けは、暗黙的な型変換に関連しています(@Darioの回答から部分的に取得):
たとえば、Python では次のようになります。
str = 5 + "hello"
# would throw an error since it does not want to cast one type to the other implicitly.
一方、PHPでは:
$str = 5 + "hello"; // equals 5 because "hello" is implicitly casted to 0
// PHP is weakly typed, thus is a very forgiving language.
静的型付けにより、コンパイル時に型の正確性をチェックできます。通常、静的に型付けされた言語はコンパイルされ、動的に型付けされた言語は解釈されます。したがって、動的型付け言語は、実行時に型付けをチェックできます。
弱い型付けとは、コンテキストに応じてオブジェクトの型が変わる可能性があることを意味します。たとえば、弱い型付けの言語では、文字列 "123" に別の数値を追加すると、数値 123 として扱われる場合があります。型付けが弱い言語の例としては、bash、awk、および PHP があります。
別の種類の弱く型付けされた言語は C です。この言語では、キャストによってメモリ アドレスのデータを別の型として扱うことができます。
厳密に型指定された言語では、オブジェクトの型は変わりません。int は常に int であり、文字列として使用しようとするとエラーになります。Java と Python はどちらも厳密に型指定されています。
動的型付けと静的型付けの違いは、型規則が適用される場合です。静的に型付けされた言語では、すべての変数とパラメーターの型をソースで宣言する必要があり、コンパイル時に適用されます。動的に型指定された言語では、型は実行時に使用されるときにのみチェックされます。したがって、Java は静的に型付けされ、Python は動的に型付けされます。
ただし、境界が少しぼやけている場合があります。たとえば、Java は静的に型付けされますが、リフレクションまたはキャストを使用するたびに (オブジェクトのコンテナーを使用する場合など)、型チェックを実行時に延期します。
同様に、ほとんどの厳密に型指定された言語は、引き続き整数と浮動小数点の間で自動的に変換されます (一部の言語では任意の精度の BigInts)。
特に他の同僚は良い仕事をしたと思います。静的型付けと動的型付けの違いを説明します。しかし、強いタイピングと弱いタイピングに関する限り、異なる理解/見解があると言わざるを得ません。
ここに 2 つの例を示します。
型変換を行うことが許可されていないため、Haskell は厳密に型指定されていると言う人もいます。
他の人 (たとえば Dario の見解) は、意図的に文字列から数値に暗黙的に変換できる言語は弱い型付けであると言いますが、他の人でさえこれを単なるダックタイピングと呼んでいます。
どちらのステートメントも、型システムの両極端ではなく、まったく異なる側面を強調しています。したがって、型システムを区別するために「強い」と「弱い」という用語を使用しないというラムジー氏の見解に、私も同意します。