「タイプセーフ」とはどういう意味ですか?
12 に答える
型安全性とは、コンパイラがコンパイル中に型を検証し、間違った型を変数に割り当てようとするとエラーをスローすることを意味します。
簡単な例:
// Fails, Trying to put an integer in a string
String one = 1;
// Also fails.
int foo = "bar";
明示的な型を渡すため、これはメソッド引数にも適用されます。
int AddTwoNumbers(int a, int b)
{
return a + b;
}
次を使用してそれを呼び出そうとした場合:
int Sum = AddTwoNumbers(5, "5");
文字列 ("5") を渡しており、整数を期待しているため、コンパイラはエラーをスローします。
JavaScript などの緩やかに型付けされた言語では、次のことができます。
function AddTwoNumbers(a, b)
{
return a + b;
}
このように呼び出すと:
Sum = AddTwoNumbers(5, "5");
Javascript は自動的に 5 を文字列に変換し、"55" を返します。これは、文字列連結に + 記号を使用する JavaScript が原因です。タイプを認識させるには、次のようにする必要があります。
function AddTwoNumbers(a, b)
{
return Number(a) + Number(b);
}
または、おそらく:
function AddOnlyTwoNumbers(a, b)
{
if (isNaN(a) || isNaN(b))
return false;
return Number(a) + Number(b);
}
このように呼び出すと:
Sum = AddTwoNumbers(5, " dogs");
Javascript は自動的に 5 を文字列に変換して追加し、「5 匹の犬」を返します。
すべての動的言語が javascript ほど寛容であるとは限りません (実際、動的言語は暗黙のうちに型指定の緩い言語を意味するわけではありません (Python を参照))、それらのいくつかは実際には無効な型キャストで実行時エラーを発生させます。
便利ですが、実行中のプログラムをテストすることによってのみ特定され、見逃されがちな多くのエラーが発生する可能性があります。個人的には、間違いを犯したかどうかをコンパイラに知らせてもらいたいと思っています。
さて、C# に戻ります...
C# はcovarianceと呼ばれる言語機能をサポートしています。これは基本的に、子型を基本型に置き換えてもエラーが発生しないことを意味します。次に例を示します。
public class Foo : Bar
{
}
ここでは、Bar をサブクラス化する新しいクラス (Foo) を作成しました。メソッドを作成できるようになりました。
void DoSomething(Bar myBar)
そして、引数として Foo または Bar を使用して呼び出すと、どちらもエラーを引き起こすことなく機能します。これが機能するのは、C# が Bar の子クラスが Bar のインターフェイスを実装することを認識しているためです。
ただし、逆はできません。
void DoSomething(Foo myFoo)
この状況では、コンパイラは Bar が Foo のインターフェースを実装していることを認識していないため、このメソッドに Bar を渡すことはできません。これは、子クラスが親クラスと大きく異なる可能性がある (通常はそうなる) ためです。
もちろん、今、私は深いところから離れ、元の質問の範囲を超えていますが、知っておくべきすべての良いことです:)
型安全性を、静的/動的型付けまたは強い/弱い型付けと混同しないでください。
タイプ セーフな言語とは、データに対して実行できる操作が、データの型によって許容される操作だけである言語です。つまり、データがタイプX
であり、X
操作をサポートしていないy
場合、言語は実行を許可しませんy(X)
。
この定義は、これがチェックされている場合のルールを設定しません。コンパイル時 (静的型付け) または実行時 (動的型付け) で、通常は例外によって発生します。静的に型付けされた言語の中には、ある型から別の型にデータをキャストできるものもあり、実行時にキャストの有効性をチェックする必要があります ( anObject
を aConsumer
にキャストしようとしていると想像してください。許容できるかどうかを知る方法)。
型安全性は、必ずしも厳密に型付けされていることを意味するわけではありません。一部の言語は、型付けが弱いことで有名ですが、それでも間違いなく型安全です。Javascript を例にとると、その型システムは弱いですが、厳密に定義されています。データの自動キャスト (文字列から int への変換など) を許可しますが、明確に定義されたルール内で行います。私の知る限りでは、Javascript プログラムが未定義の方法で動作するケースはありません。十分に賢ければ (私はそうではありませんが)、Javascript コードを読んだときに何が起こるかを予測できるはずです。
タイプセーフでないプログラミング言語の例は C です。配列の境界外の配列値の読み取り/書き込みは、仕様によって未定義の動作をします。何が起こるかを予測することは不可能です。C は型システムを持つ言語ですが、型安全ではありません。
ここでの多くの回答は、型安全性を静的型付けおよび動的型付けと混同しています。動的に型付けされた言語(smalltalkなど)も型セーフにすることができます。
簡単な答え:操作が未定義の動作につながる場合、言語はタイプセーフと見なされます。多くの人は、言語を厳密に型指定するために必要な明示的な型変換の要件を検討しています。自動変換は、明確に定義されているが予期しない/直感的でない動作につながる場合があるためです。
コンプサイエンス専攻ではなくリベラルアーツ専攻からの説明:
言語または言語機能がタイプセーフであると人々が言う場合、その言語は、たとえば、整数でないものを整数を期待するロジックに渡すことを防ぐのに役立つことを意味します。
たとえば、C# では、関数を次のように定義します。
void foo(int arg)
コンパイラは、私がこれを行うのを止めます:
// call foo
foo("hello world")
他の言語では、コンパイラは私を止めません (またはコンパイラがありません...)。そのため、文字列がロジックに渡され、おそらく何か悪いことが起こるでしょう。
型安全な言語は、「コンパイル時」にもっとキャッチしようとします。
欠点として、型安全な言語では、"123" のような文字列があり、それを int のように操作したい場合、文字列を int に変換するためのコードをさらに記述する必要があります。 123 のように、「答えは 123 です」のようなメッセージで使用したい場合は、文字列に変換/キャストするためのコードをさらに記述する必要があります。
理解を深めるには、タイプ セーフ言語 (C#) とタイプ セーフでない言語 (javascript) のコードを示す以下のビデオをご覧ください。
http://www.youtube.com/watch?v=Rlw_njQhkxw
それでは長文です。
型安全性とは、型エラーを防ぐことを意味します。型エラーは、ある型のデータ型が別の型に不明なまま割り当てられると発生し、望ましくない結果が得られます。
たとえば、JavaScript はタイプ セーフな言語ではありません。以下のコードでは、「num」は数値変数で、「str」は文字列です。Javascript を使用すると、「num + str」を実行できます。これで、GUESS は算術または連結を実行できます。
以下のコードの場合、結果は「55」ですが、重要な点は、どのような操作を行うのか混乱を招くことです。
これは、javascript が型安全な言語ではないために発生しています。制限なしで、あるタイプのデータを他のタイプに設定できます。
<script>
var num = 5; // numeric
var str = "5"; // string
var z = num + str; // arthimetic or concat ????
alert(z); // displays “55”
</script>
C# はタイプ セーフな言語です。あるデータ型を別のデータ型に割り当てることはできません。以下のコードでは、異なるデータ型に対して「+」演算子を使用できません。
タイプセーフとは、プログラムで、変数、戻り値、または引数のデータのタイプが特定の基準内に収まらなければならないことを意味します。
実際には、これは7(整数型)が「7」(文字列型の引用符で囲まれた文字)とは異なることを意味します。
PHP、Javascript、およびその他の動的スクリプト言語は、「7」+ 3を追加しようとすると、(文字列)「7」を(整数)7に変換するという点で、通常は弱く型付けされていますが、これを行う必要がある場合もあります。明示的に(そしてJavascriptは連結に「+」文字を使用します)。
C / C ++ / Javaはそれを理解しないか、代わりに結果を「73」に連結します。型安全性は、型要件を明示的にすることにより、コード内のこれらの型のバグを防ぎます。
型安全性は非常に便利です。上記の"7"+ 3の解決策は、cast(int) "7" + 3(10に等しい)と入力することです。
この説明を試してみてください...
TypeSafe とは、コンパイル時に変数が適切に割り当てられているかどうかを静的にチェックすることを意味します。たとえば、文字列または整数を考えます。これら 2 つの異なるデータ型は相互に割り当てることはできません (つまり、整数を文字列に割り当てることも、文字列を整数に割り当てることもできません)。
タイプセーフでない動作については、次のことを考慮してください。
object x = 89;
int y;
これを行おうとすると:
y = x;
コンパイラは、System.Object を Integer に変換できないというエラーをスローします。明示的に行う必要があります。1つの方法は次のとおりです。
y = Convert.ToInt32( x );
上記の代入はタイプセーフではありません。タイプセーフな割り当ては、型を互いに直接割り当てることができる場所です。
ASP.NET には、型保証されていないコレクションがたくさんあります (アプリケーション、セッション、ビューステート コレクションなど)。これらのコレクションに関する良いニュースは、(複数のサーバー状態管理に関する考慮事項を最小限に抑えて) 3 つのコレクションのいずれにもほとんどすべてのデータ型を入れることができることです。悪いニュース: これらのコレクションはタイプ セーフではないため、取得するときに値を適切にキャストする必要があります。
例えば:
Session[ "x" ] = 34;
正常に動作します。ただし、整数値を代入するには、次のことが必要です。
int i = Convert.ToInt32( Session[ "x" ] );
タイプセーフなコレクションを簡単に実装するのに機能が役立つ方法については、ジェネリックについてお読みください。
C# はタイプセーフな言語ですが、C# 4.0 に関する記事に注意してください。興味深い動的な可能性が浮かび上がってきます (C# が基本的に Option Strict: Off になっているのは良いことでしょうか...後で説明します)。
Type-Safe は、アクセスが許可されているメモリ位置にのみ、明確に定義された許可された方法でのみアクセスするコードです。タイプ セーフ コードは、オブジェクトに対して無効な操作を実行できません。C# および VB.NET 言語コンパイラは、常にタイプ セーフなコードを生成します。このコードは、JIT コンパイル中にタイプ セーフであることが検証されます。
タイプ セーフとは、プログラム変数に割り当てることができる一連の値が、明確に定義されたテスト可能な基準に適合する必要があることを意味します。変数を操作するアルゴリズムは、変数が明確に定義された値のセットの 1 つだけを取ると信頼できるため、タイプ セーフな変数はより堅牢なプログラムにつながります。この信頼を維持することで、データとプログラムの整合性と品質が保証されます。
多くの変数では、変数に割り当てられる値のセットは、プログラムの作成時に定義されます。たとえば、「色」という名前の変数は、「赤」、「緑」、または「青」の値を取ることができ、それ以外の値を取ることはできません。他の変数の場合、これらの基準は実行時に変更される場合があります。たとえば、「色」と呼ばれる変数は、リレーショナル データベースの「色」テーブルの「名前」列の値のみを受け取ることができます。ここで、「赤」、「緑」、および「青」は 3 つの値です。 「色」テーブルの「名前」の場合、プログラムの実行中にコンピュータープログラムの他の部分がそのリストに追加できる場合があり、変数は色テーブルに追加された後に新しい値を取ることができます.
多くの型安全言語は、変数の型を厳密に定義することを主張し、変数に同じ「型」の値を割り当てることのみを許可することにより、「型安全」の錯覚を与えます。このアプローチにはいくつかの問題があります。たとえば、あるプログラムが、人が生まれた年である "yearOfBirth" という変数を持っている場合、それを短い整数として型キャストしたくなります。ただし、短整数ではありません。今年は、2009 年より小さく、-10000 より大きい数値です。ただし、このセットは、プログラムが実行されるたびに 1 ずつ増加します。これを「short int」にするのは適切ではありません。この変数をタイプ セーフにするために必要なのは、数値が常に -10000 より大きく、次の暦年より小さいことを保証するランタイム検証関数です。
Perl、Python、Ruby、SQLite、Lua などの動的型付け (またはダック型付け、マニフェスト型付け) を使用する言語には、型付き変数の概念がありません。これにより、プログラマーはすべての変数に対して実行時検証ルーチンを作成して、変数が正しいことを確認するか、説明のつかない実行時例外の結果に耐える必要があります。私の経験では、C、C++、Java、C# などの静的に型付けされた言語のプログラマーは、タイプ セーフの利点を得るために必要なのは静的に定義された型だけであると考えがちです。これは、多くの有用なコンピューター プログラムにはまったく当てはまらず、特定のコンピューター プログラムに当てはまるかどうかを予測することは困難です。
長いものと短いもの....タイプセーフが必要ですか?その場合は、ランタイム関数を記述して、変数に値が割り当てられたときに、明確に定義された基準に準拠するようにします。欠点は、各プログラム変数の基準を明示的に定義する必要があるため、ほとんどのコンピューター プログラムでドメイン分析が非常に困難になることです。