型の自動キャストを行う言語とそうでない言語はたくさんあります。私はそれがあまり良い考えだとは思わないことを前もって言わなければなりません。私は自分の言語でより原則的な動作を好みますが、自動キャストの便利さと冗長性の欠如を好む人もいます。
パール
Perl は、型の自動キャストを行う言語の例です。これが非常に混乱を招く可能性がある場合を示す、非常に楽しい例を次に示します。
print "bob" eq "bob";
print "nancy" eq "nancy";
print "bob" == "bob";
print "nancy" == "nancy";
上記のプログラムは、1 (true) を 4 回ではなく 3 回出力します。なぜ4番目ではないのですか?「ナンシー」は == 「ナンシー」ではありません。なぜだめですか?== は数値等価演算子だからです。eq は文字列の等価性を表します。文字列は eq のように比較されますが、== では自動的に数値に変換されます。「ボブ」は何番に等しい?もちろんゼロ。プレフィックスとして数字を持たない文字列は、ゼロとして解釈されます。このため、"bob" == "chris" は true です。「ナンシー」==「ナンシー」ではないのはなぜですか? 「ナンシー」がゼロでないのはなぜですか? それは「数字ではない」を「ナン」と読むからです。NaN は別の NaN と等しくありません。個人的には、これは紛らわしいと思います。
Javascript
Javascript は、型の自動キャストを行う言語の別の例です。
'5' - 3
その表現の結果は何ですか?2!とても良い。
'5' + 3
そいつの結果は?8? 違う!「53」です。
混乱している?良い。うわーJavascript、そのような良い慣習、非常に理にかなっている. これは、型の自動キャストに基づく一連の非常に面白い Javascript 評価です。
なぜ誰もがこれを行うのでしょうか!?
厳選されたいくつかのホラー ストーリーを見た後、全世界で最も人気のある 2 つのプログラミング言語を発明するのに十分な知性を持つ人々が、なぜそんなにばかげたことをするのか自問するかもしれません。私は型の自動キャストが好きではありませんが、公平を期すために、それには議論があります。純粋なバグではありません。次の Haskell 式を検討してください。
length [1,2,3,4] / 2
これは何に等しいですか?2? 2.0? いいえ!型エラーのためコンパイルできません。length は Int を返し、それを分割することはできません。これを機能させるには、fromIntegral を呼び出して、長さを分数に明示的にキャストする必要があります。
fromIntegral (length [1,2,3,4]) / 2
プログラム内を動き回る整数と浮動小数点数を使用して多くの計算を行っている場合、これは間違いなく非常に面倒です。しかし、なぜナンシーがナンシーと等しくなく、実際にはクリスがボブと等しいのかを理解しなければならないよりも、私はそれを大いに望んでいます.
ハッピーミディアム?
スキームには数値タイプが 1 つしかありません。float、fraction、int を自動的に変換し、期待どおりに処理します。それはあなたが何を意味するかを知っているので、明示的なキャストなしでリストの長さを分割することができます。しかし、いいえ、文字列を密かに数値に変換することは決してありません。文字列は数値ではありません。それはばかげています。;)
あなたの例
あなたの例については、それが論理的であるかどうかはわかりません。紛らわしいです、はい。スタック オーバーフローでここにいるということですね。あなたが3を得ている理由は、ロスが言ったように、-3が2の賛辞の単位として解釈されており、はるかに高い数であるか、または最小の結果が-3であり、それが負の値を削除して unsigned int にします。問題は、結果を unsigned int に入れるように求めたが、結果が負であることです。したがって、型の自動キャストのコンテキストでは論理的であると言えますが、その型の自動キャストは混乱を招きます。おそらく、あちこちで明示的な型キャストを行う必要がなく、時々このような奇妙な動作で代償を払う必要がなくなります。