1105

新しいプログラミング言語は動的に型付けされるとよく​​耳にしますが、言語が動的に型付けされるのか静的に型付けされるのかというと、実際にはどういう意味ですか?

4

17 に答える 17

997

静的に型付けされた言語

変数の型がコンパイル時にわかっている場合、言語は静的に型付けされます。一部の言語では、これは、プログラマーが各変数のタイプを指定する必要があることを意味します。他の言語(例:Java、C、C ++)は、何らかの形の型推論、変数の型を推測する型システムの機能(例:OCaml、Haskell、Scala、Kotlin)を提供します。

ここでの主な利点は、コンパイラがあらゆる種類のチェックを実行できることです。したがって、非常に早い段階で多くの些細なバグが検出されます。

例:C、C ++、Java、Rust、Go、Scala

動的型付け言語

タイプが実行時の値に関連付けられており、変数/フィールドなどの名前が付けられていない場合、言語は動的に型付けされます。これは、(型推論で静的に型付けされた言語を使用しない限り)毎回型を指定する必要がないため、プログラマーとしては少し速く書くことができることを意味します。

例:Perl、Ruby、Python、PHP、JavaScript、Erlang

とにかく静的型チェックを行うコンパイラがないため、ほとんどのスクリプト言語にはこの機能がありますが、インタプリタが変数の型を誤って解釈することによるバグを探していることに気付くかもしれません。幸いなことに、スクリプトは小さい傾向があるため、バグを隠す場所はそれほど多くありません。

ほとんどの動的型付け言語では、型情報を提供できますが、必須ではありません。現在開発中の言語の1つであるRascalは、関数内で動的型付けを可能にするハイブリッドアプローチを採用していますが、関数シグネチャには静的型付けを適用しています。

于 2009-10-04T23:11:04.030 に答える
464

静的に型付けされたプログラミング言語は、実行時ではなくコンパイル時に型チェック(つまり、型の制約を検証および適用するプロセス)を実行します。

動的に型付けされたプログラミング言語は、コンパイル時ではなく実行時に型チェックを行います。

静的に型付けされた言語の例は次のとおりです:Java、C、C ++

動的に型付けされた言語の例は、Perl、Ruby、Python、PHP、JavaScriptです。

于 2009-10-05T14:12:37.073 に答える
347

Python(動的型付け)とGo(静的型付け)が型エラーを処理する方法を対比する例を次に示します。

def silly(a):
    if a > 0:
        print 'Hi'
    else:
        print 5 + '3'

Pythonは実行時に型チェックを行うため、次のようになります。

silly(2)

完全に正常に実行され、期待される出力を生成しますHi。問題のある行がヒットした場合にのみエラーが発生します。

silly(-1)

生産する

TypeError: unsupported operand type(s) for +: 'int' and 'str'

関連する行が実際に実行されたためです。

一方、Goは、コンパイル時に型チェックを行います。

package main

import ("fmt"
)

func silly(a int) {
    if (a > 0) {
        fmt.Println("Hi")
    } else {
        fmt.Println("3" + 5)
    }
}

func main() {
    silly(2)
}

上記はコンパイルされず、次のエラーが発生します。

invalid operation: "3" + 5 (mismatched types string and int)
于 2015-01-06T02:49:56.393 に答える
185

簡単に言うと、静的に型付けされた言語では、変数の型は静的です。つまり、変数を型に設定すると、それを変更することはできません。これは、入力が参照する値ではなく変数に関連付けられているためです。

たとえば、Javaの場合:

String str = "Hello";  // variable str statically typed as string
str = 5;               // would throw an error since str is
                       // supposed to be a string only

一方、動的に型付けされた言語では、変数の型は動的です。つまり、変数を型に設定した後、それを変更できます。これは、入力が変数自体ではなく、想定する値に関連付けられているためです。

たとえば、Pythonの場合:

some_str = "Hello"  # variable some_str is linked to a string value
some_str = 5        # now it is linked to an integer value; perfectly OK

したがって、動的に型付けされた言語の変数は、型付き値への単なるジェネリックポインターと考えるのが最善です。

要約すると、typeは、言語自体ではなく、言語の変数をdescribe(またはdescribeする必要があります)と入力します。静的に型付けされた変数を持つ言語として、動的に型付けされた変数を持つ言語としてより適切に使用できたはずです。

静的に型付けされた言語は一般にコンパイルされた言語であるため、コンパイラーは型をチェックします(型は実行時に後で変更することは許可されていないため、完全に理にかなっていますか?)。

動的に型付けされた言語は一般に解釈されるため、型チェック(存在する場合)は、それらが使用される実行時に行われます。もちろん、これにはパフォーマンスコストがかかり、動的言語(python、ruby、phpなど)が型指定された言語(java、c#など)ほど拡張性が高くない理由の1つです。別の見方をすれば、静的に型付けされた言語は、より多くの初期費用がかかります。通常、より多くのコード、より難しいコードを書くことになります。しかし、それは後で報われます。

良い点は、両方が反対側から機能を借用していることです。型付き言語には、c#のジェネリックや動的ライブラリなどのより動的な機能が組み込まれています。動的言語には、Pythonの型注釈や、PHPのHACKバリアントなど、より多くの型チェックが含まれています。これらは通常、言語のコアではなく、要求する。

技術の選択に関しては、どちらの側も他方に対して本質的な優位性を持っていません。より多くの制御を開始するか、柔軟性を求めるかは、好みの問題です。仕事に適したツールを選ぶだけで、切り替えを検討する前に、反対の観点から何が利用できるかを確認してください。

于 2015-11-30T17:28:33.867 に答える
45

http://en.wikipedia.org/wiki/Type_system

静的型付け

プログラミング言語は、実行時ではなくコンパイル時に型チェックが実行されるときに静的型付けを使用すると言われています。静的型付けでは、型は値ではなく変数に関連付けられます。静的に型付けされた言語には、Ada、C、C ++、C#、JADE、Java、Fortran、Haskell、ML、Pascal、Perl(スカラー、配列、ハッシュ、サブルーチンの区別に関して)、Scalaが含まれます。静的型付けは、プログラム検証の限定された形式です(型の安全性を参照)。したがって、開発サイクルの早い段階で多くの型エラーを検出できます。静的型チェッカーは、コンパイル時に判別できる型情報のみを評価しますが、チェックされた条件がプログラムのすべての可能な実行に当てはまることを確認できるため、プログラムが実行されるたびに型チェックを繰り返す必要がありません。

コンパイル中に型情報を評価するため、実行時にのみ使用できる型情報が不足しているため、静的型チェッカーは保守的です。それらは、実行時に正常に動作する可能性があるが、静的に適切に型指定されていると判断できない一部のプログラムを拒否します。たとえば、式が実行時に常にtrueと評価されたとしても、コードを含むプログラムは

if <complex test> then 42 else <type error>

静的分析ではelseブランチが取得されないと判断できないため、タイプが正しくないとして拒否されます。[1] 静的型チェッカーの保守的な動作は、falseと評価される頻度が低い場合に有利です。静的型チェッカーは、めったに使用されないコードパスの型エラーを検出できます。静的タイプチェックがないと、100%のコードカバレッジを使用したコードカバレッジテストでも、そのようなタイプエラーを見つけることができない場合があります。値が作成されるすべての場所と特定の値が使用されるすべての場所の組み合わせを考慮に入れる必要があるため、コードカバレッジテストではこのようなタイプエラーを検出できない場合があります。

最も広く使用されている静的型付け言語は、正式には型安全ではありません。プログラミング言語の仕様には「抜け穴」があり、プログラマーは静的型チェッカーによって実行される検証を回避するコードを記述できるため、より広範囲の問題に対処できます。たとえば、JavaおよびほとんどのCスタイルの言語には型のパンニングがあり、HaskellにはunsafePerformIOなどの機能があります。このような操作は、プログラムの実行時に値を誤って入力するために望ましくない動作を引き起こす可能性があるため、実行時に安全ではない可能性があります。

動的型付け

プログラミング言語は、その型チェックの大部分がコンパイル時ではなく実行時に実行される場合、動的に型付けされる、または単に「動的」であると言われます。動的型付けでは、型は変数ではなく値に関連付けられます。動的に型付けされた言語には、Groovy、JavaScript、Lisp、Lua、Objective-C、Perl(ユーザー定義型に関しては、組み込み型ではない)、PHP、Prolog、Python、Ruby、Smalltalk、Tclが含まれます。静的型付けと比較すると、動的型付けはより柔軟になります(たとえば、プログラムが実行時データに基づいて型と機能を生成できるようにすることで)。ただし、事前の保証は少なくなります。これは、動的型付け言語が、静的型チェッカーによって無効と判断される可能性のあるいくつかのプログラムを受け入れて実行しようとするためです。

動的型付けにより、実行時の型エラーが発生する可能性があります。つまり、実行時に値に予期しない型が含まれ、その型に対して無意味な操作が適用される場合があります。この操作は、プログラミングの間違いがあった場所、つまり、間違ったタイプのデータが本来あるべき場所に渡された場所のずっと後に発生する可能性があります。これにより、バグを見つけるのが難しくなります。

動的に型付けされた言語システムは、静的に型付けされたいとこと比較して、ソースコードに対する「コンパイル時」のチェックが少なくなります(ただし、たとえば、プログラムが構文的に正しいかどうかをチェックします)。実行時チェックは、動的情報だけでなく、コンパイル中に存在した情報も使用できるため、より高度になる可能性があります。一方、ランタイムチェックは、プログラムの特定の実行で条件が保持されることを表明するだけであり、これらのチェックはプログラムの実行ごとに繰り返されます。

動的型付け言語での開発は、多くの場合、単体テストなどのプログラミング手法によってサポートされます。テストは、プロのソフトウェア開発における重要なプラクティスであり、動的型付け言語では特に重要です。実際には、プログラムが正しく動作することを確認するために行われるテストでは、静的型チェックよりもはるかに広い範囲のエラーを検出できますが、逆に、テストと静的型チェックの両方で検出できるエラーを包括的に検索することはできません。テストはソフトウェアビルドサイクルに組み込むことができます。この場合、プログラムユーザーはそのようなテストを手動で実行する必要がないため、「コンパイル時」のチェックと考えることができます。

参考文献

  1. ピアス、ベンジャミン(2002)。タイプとプログラミング言語。MITプレス。ISBN0-262-16209-1。
于 2009-10-04T22:37:15.350 に答える
16

「動的に型付けされた」という用語は、残念ながら誤解を招く恐れがあります。すべての言語は静的に型付けされており、型は式のプロパティです(一部の人が考えるような値ではありません)。ただし、一部の言語には1つのタイプしかありません。これらはユニタイプ言語と呼ばれます。このような言語の一例は、型指定されていないラムダ計算です。

型指定されていないラムダ計算では、すべての項はラムダ項であり、ある項に対して実行できる唯一の操作は、それを別の項に適用することです。したがって、すべての操作は常に無限再帰またはラムダ項のいずれかをもたらしますが、エラーを通知することはありません。

ただし、型指定されていないラムダ計算をプリミティブ数と算術演算で拡張すると、2つのラムダ項を足し合わせるなどの無意味な演算を実行できます(λx.x) + (λy.y)。これが発生したときにエラーを通知することが唯一の正しいことであると主張することもできますが、これを実行するには、各値に、用語がラムダ用語であるか数値であるかを示すインジケーターをタグ付けする必要があります。次に、加算演算子は、両方の引数が実際に数値としてタグ付けされていることを確認し、タグ付けされていない場合は、エラーを通知します。タイプはプログラムのプロパティであり、それらのプログラムによって生成された値ではないため、これらのタグはタイプではないことに注意してください。

これを行う単一型の言語は、動的型付きと呼ばれます。

JavaScript、Python、Rubyなどの言語はすべてユニタイプです。繰り返しtypeofますが、JavaScriptの演算子とtypePythonの関数には誤解を招くような名前が付いています。タイプではなく、オペランドに関連付けられたタグを返します。同様にdynamic_cast、C ++およびinstanceofJavaでは、型チェックを実行しません。

于 2015-10-12T16:57:29.557 に答える
14

コンパイル済みvs.解釈済み

「ソースコードを翻訳するとき」

  • ソースコード:元のコード(通常、人間がコンピューターに入力します)
  • 翻訳:ソースコードをコンピューターが読み取れるもの(つまり、機械語)に変換する
  • 実行時:プログラムがコマンドを実行している期間(コンパイル後、コンパイルされている場合)
  • コンパイル言語:実行時に翻訳されたコード
  • 通訳言語:実行中にその場で翻訳されたコード

タイピング

「タイプをチェックするとき」

5 + '3'は、GoやPythonなどの強く型付けされた言語での型エラーの例です。これは、「型強制」-> 2つの型のマージなど、特定のコンテキストで値が型を変更する機能を許可しないためです。JavaScriptなどの弱く型付け'53'された言語は、型エラーをスローしません(結果は)。

  • 静的:実行時にチェックされるタイプ
  • 動的:実行中にオンザフライでチェックされるタイプ

「Static&Compiled」と「Dynamic&Interpreted」の定義は非常に似ていますが、「タイプがチェックされるとき」と「ソースコードが翻訳されるとき」であることを忘れないでください。

言語がコンパイルされているかインタプリタされているかに関係なく、同じタイプのエラーが発生します。これらの用語を概念的に分離する必要があります。


Pythonの例

動的、解釈

def silly(a):
    if a > 0:
        print 'Hi'
    else:
        print 5 + '3'

silly(2)

Pythonは解釈され、動的に型付けされるため、実行中のコードの変換と型チェックのみを行います。elseブロックが実行されることはないので、見5 + '3'られることさえありません!

静的に型付けされた場合はどうなりますか?

コードが実行される前に、型エラーがスローされます。解釈されても、実行前に型チェックを実行します。

コンパイルされた場合はどうなりますか?

elseブロックは実行前に変換/確認されますが、動的に型指定されるため、エラーはスローされません。動的に型付けされた言語は、実行されるまで型をチェックせず、その行は実行されません。


例を見る

静的、コンパイル済み

package main

import ("fmt"
)

func silly(a int) {
  if (a > 0) {
      fmt.Println("Hi")
  } else {
      fmt.Println("3" + 5)
  }
}

func main() {
  silly(2)
}

実行前にタイプがチェックされ(静的)、タイプエラーがすぐにキャッチされます!型が解釈された場合でも、実行前に型がチェックされ、同じ結果になります。動的である場合、コンパイル中にコードが確認されても、エラーはスローされません。


パフォーマンス

コンパイルされた言語は、静的に型付けされている場合(動的に型付けされている場合と比較して)、実行時のパフォーマンスが向上します。タイプの知識により、マシンコードの最適化が可能になります。

静的に型付けされた言語は、実行中に型を動的にチェックする必要がないため、実行時に本質的にパフォーマンスが向上します(実行前にチェックします)。

同様に、コンパイルされた言語は、コードをその場で「解釈」/翻訳する必要がなく、コードがすでに翻訳されているため、実行時に高速になります。

コンパイルされた言語と静的に型付けされた言語の両方で、それぞれ翻訳と型チェックを実行する前に遅延が発生することに注意してください。


その他の違い

静的型付けは、実行中にエラーを見つけるのではなく、エラーを早期にキャッチします(特に長いプログラムに役立ちます)。プログラム内のどこでもタイプエラーを許可せず、変数がタイプを変更できないようにするという点で、より「厳密」です。これにより、意図しないエラーがさらに防止されます。

num = 2
num = '3' // ERROR

動的型付けはより柔軟であり、一部の人はそれを高く評価しています。通常、変数で型を変更できるため、予期しないエラーが発生する可能性があります。

于 2017-12-08T21:25:00.567 に答える
11

静的に型付けされた言語:各変数と式は、コンパイル時にすでに認識されています。

int a;aは実行時に整数型の値のみを取ることができます)

例:C、C ++、Java

動的に型付けされた言語:変数は実行時に異なる値を受け取ることができ、その型は実行時に定義されます。

var a;aは実行時に任意の種類の値を取ることができます)

例:Ruby、Python。

于 2017-10-01T14:35:07.260 に答える
5

静的に型付けされた言語は、コンパイル時に型チェックを行い、型を変更することはできません。(型キャストコメントでかわいくならないでください。新しい変数/参照が作成されます)。

動的に型付けされた言語は実行時に型チェックし、変数の型は実行時に変更できます。

于 2016-07-27T06:56:38.793 に答える
4

甘くてシンプルな定義ですが、ニーズに適合します。静的に型付けされた言語は、スコープ全体の変数に型をバインドします(セグメント:SCALA)動的に型付けされた言語は、変数によって参照される実際の値に型をバインドします。

于 2016-11-29T06:37:47.477 に答える
3
  • 静的に型付けされた言語では、変数はコンパイル時に既知の型に関連付けられ、その型はプログラムの実行中は変更されません。同様に、変数には、既知の/指定されたタイプのインスタンスである値のみを割り当てることができます。
  • 動的に型付けされた言語では、変数には型がなく、実行中の値は任意の形や形式にすることができます。
于 2016-10-29T20:18:48.293 に答える
3

静的型付き言語(コンパイラーはメソッド呼び出しを解決し、参照をコンパイルします):

  • 通常、パフォーマンスが向上します
  • より高速なコンパイルエラーフィードバック
  • より良いIDEサポート
  • 未定義のデータ形式での作業には適していません
  • モデルが定義されていない場合、開発を開始するのが難しい
  • コンパイル時間が長くなります
  • 多くの場合、より多くのコードを書く必要があります

動的型付け言語(実行中のプログラムで行われる決定):

  • パフォーマンスの低下
  • より迅速な開発
  • 一部のバグは、実行時にのみ検出される可能性があります
  • 未定義のデータ形式に適しています(メタプログラミング)
于 2019-07-16T06:09:03.700 に答える
2

C ++、Javaのような静的に型付けされた言語と、Pythonのような動的に型付けされた言語は、変数の型の実行に関してのみ異なります。 静的に型付けされた言語には変数の静的データ型があります。ここでは、コンパイル中にデータ型がチェックされるため、デバッグがはるかに簡単になります...動的に型付けされた言語は同じことをしませんが、プログラムを実行するデータ型がチェックされます。デバッグは少し難しいです。

さらに、それらの違いは非常に小さく、強く型付けされた言語と弱く型付けされた言語に関連付けることができます。強く型付けされた言語では、ある型を別の型として使用することはできません。CおよびC++...一方、弱い型の言語ではeg.pythonが許可されます

于 2018-08-17T10:21:12.910 に答える
2

静的に型付け

タイプは実行時にチェックされるため、ミスを早期に発見できます。

例=c++

動的に型付け

タイプは実行中にチェックされます。

例=Python

于 2019-10-05T22:59:19.573 に答える
2

静的型: コンパイル時に実行される型チェック

静的型言語の実際の意味:

  • 変数のタイプを指定する必要があります
  • 変数は特定のタイプのオブジェクトのみを参照できます*
  • 値の型チェックはコンパイル時に実行され、型チェックはその時点で報告されます
  • その特定のタイプの値を格納するために、コンパイル時にメモリが割り当てられます

静的型言語の例は、C、C ++、Javaです。

動的タイプ: 実行時に実行されるタイプチェック

動的型言語の実際の意味:

  • 変数のタイプを指定する必要はありません
  • 同じ変数が異なるタイプのオブジェクトを参照できます

Python、Rubyは動的型言語の例です。


*一部のオブジェクトは、型キャストすることでさまざまなタイプの変数に割り当てることができます(CやC ++などの言語では非常に一般的な方法です)。

于 2021-04-08T16:09:50.600 に答える
0

動的に型付けされた言語は、どの変数型を使用する必要があるかを考えるオーバーヘッドなしに、アルゴリズムの概念をすばやくプロトタイプ化するのに役立ちます(静的に型付けされた言語では必要です)。

于 2018-03-14T16:34:05.277 に答える
-17

静的型付け: JavaやScalaなどの言語は静的型付けされています。

変数は、コードで使用する前に定義して初期化する必要があります。

例:int x; x = 10;

System.out.println(x);

動的型付け: Perlは動的型付け言語です。

変数は、コードで使用する前に初期化する必要はありません。

y = 10; コードの後半でこの変数を使用します

于 2013-06-27T07:19:05.073 に答える