命令型プログラミング言語での型のキャストと変換に違いはありますか?


8

StackOverflow での議論で問題が浮上しました。

(オブジェクトのタイプに関して)キャスト変換の 2つの概念の間に明確な違いはありますか、それともこれら2つの単語はまったく同じですか?C ++、Python、Java以外の言語はどうですか?EDIT:どのような問題の種類は次のように、プリミティブ型であるかintfloat

回答:


5

理論的には、2つの概念は大きく異なります。

型キャストとは、あるタイプ(大まかに言えば、オブジェクト構造)を別のタイプに交換することを指し、タイプ変換とは、値(大まかに言えば、オブジェクトのコンテンツ)を変換することを指します。これにより、新しいタイプに属するものとして解釈されます。理論的には、それらが混合することはありません

とは言っても、実際には、別のものなしで1つを持つことができます、ほとんどの場合、それは悪い考えです。オブジェクトの内容を変更せずに、オブジェクトの構造の認識を変更することはほとんど意味がありません。実際には、ほとんど同じです


3
これは、Cのような弱く型付けされた言語でさらに楽しくなります。メモリのセクションを別の型として単に参照できます!
シェルドンワルケンティン

Cでは「キャスト」と「コンバージョン」という用語が使われているわけではありません。私の答えをご覧ください。
キース・トンプソン、

質問を編集しました。それについて何か考えはありますか?ありがとう!
krlmlr

プリミティブの答えは変わりません。
blueberryfields

「オブジェクトのコンテンツを変更することなく、オブジェクトの構造の認識を変更することはほとんど意味がありません。」これがサブタイピングとポリモーフィズムの要点ではありませんか?AbstractSpriteそれが実際にあることをまったく知らない間、参照を保持していますBigGreenTreeSpriteか?
sara 2016年

3

言語によって、「キャスト」と「変換」という言葉の定義は異なります。この質問は、特定の言語を参照すること以外には意味がないと思います。

たとえば、Cでは、「キャスト」という用語は、変換される式の前の括弧内の型名で構成される明示的なキャスト演算子のみを適切に指します。「変換」は、あるタイプの値を別のタイプの値に変換します。一部の変換は、表現を構成するビットを再解釈することによって実装されますが、値から値への変換として定義されています。(はい、それはポインター変換でも同じです。異なるポインター型が異なる表現を持つことは可能です。)

Cには「暗黙のキャスト」などはありません。

一部の変換は明示的であり、キャスト演算子によって指定されます。その他は暗黙的であり、あるタイプの式が別のタイプの式を必要とするコンテキストで使用される場合に、特定のケースに適用されます。実行される変換は、どちらの場合でもまったく同じです。

例えば:

double x = 1.23;
int y = (int)x;  /* A cast, or explicit conversion, setting y to 1 */
int z = x;       /* An implicit conversion, setting z to 1. */

C ++も同様です。それはCと同じキャストと変換を持っており、それはCスタイルのキャスト式に関数表記相当を追加し、プラス4つのより具体的なキーワード:const_castdynamic_castreinterpret_cast、とstatic_cast


浮動小数点数を整数型に、または大きな整数型を小さな型に変換する手段としてキャストを嫌うのは私だけですか?私の考えでは、キャストは言語デザイナーがもっともらしい動作を1つしか選択できない状況に適しているはずです。また、異なる動作が異なるコンテキストで意味をなす場合は、他の変換手段を使用する必要があります。例えば、一つは言語が作るべきであると主張することができ(int)1.5-2*(int)(-1.5)、収率3、4、5、または6を、しかし場合(int)に交換されていたtruncIntroundPeriodicIntfloorInt、またはroundEvenInt...、
supercat

...あいまいさはありません。同様に、長い整数型を短い整数型にキャストする場合、小さい型に適合しない数値が予想され、折り返す必要がある場合や、そのような数値が予期せず、例外をトリガーする必要がある場合があります。そのようなキャストでは言語が異なると動作が異なるため、キャストがどのような動作をするべきかを自明にすることはほとんどできません。言語にラッピング整数型と非ラッピング整数型の両方がない場合(適切な設計概念、私はそうは知りませんが、IMHO)、ラッピングが期待されるかどうかを指定することは役立つと思われます。
スーパーキャット2014年

@supercat:Cにおいて、少なくとも、キャストが常に同じタイプのオブジェクトに割り当てることによって暗黙的に実行される変換の同じ種類を指定- あればそれができるコンバージョン(算術タイプ間のほとんどのもの)の一つです暗黙的に行われます。その他の種類の変換、たとえば、浮動小数点の丸め/切り捨ての種類の指定は、関数呼び出しを介して行うことができます。
キース・トンプソン

確かに関数を使用できます。私のポイントは、関数またはメンバー、結果が元の値を表さない可能性のある変換を実行する適切な手段と見なされるべきだと私は思うということです。Cは暗黙的な浮動小数点から整数への変換を許可していることを知っています。互換性により、Cはおそらく常にそうしなければならないことを指示しますが、そうである必要はありません。Pascalは、呼び出しを必要とするRoundか、Trunc-IMHOをはるかにクリーンなデザインにします。
スーパーキャット2014年

1

キャスト中、あるクラスのインスタンスを別のクラスのインスタンスであるかのように読み取ります。このクラスのペアに適用できるかどうかは不明です。チェック以外のランタイム作業はありません。多くの場合、コンパイル段階で非互換性が発生する可能性があります。

変換中に、あるクラスのインスタンスのフィールドを別のクラスのインスタンスに再結合または再カウントします。そのための関数がある場合、それはこのまさにそのインスタンスに適用可能かそうでないかです。すべての作業は実行時に行われます。コンパイル中にエラーをチェックできませんでした。


それは言語固有に聞こえます。あなたは何語を参照していますか?
キース・トンプソン、

Java、C ++、C#、Pascal / Delphi。
Gangnus

C ++は、C標準と同じ方法で「キャスト」および「変換」という用語を使用し、いくつかの特殊なキャストキーワードを追加しています。私の答えを見てください。
キース・トンプソン、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.