programming-languages - 配列 - ポインタ と 整数 と の 比較 を 行なっ てい ます null




言語にNULLを含めないことの意味 (7)

プログラミング言語ではNULLは必要ないことを私は知っています。そして私は最近、自分のプログラミング言語にNULLを含めないことにしました。 宣言は初期化によって行われるので、初期化されていない変数を持つことは不可能です。 私は、これによりNullPointerExceptionが排除され、より意味のある例外が発生するか、単に特定の種類のバグがNullPointerExceptionしなくなることを望んでいます。

もちろん、この言語はC言語で実装されているので、カバーの下にはNULLが使用されます。

私の質問は、エラーフラグとして(これは例外で処理されます)、またはリンクリストやバイナリツリーなどのデータ構造の終点(これは識別された共用体で処理される)としてNULLを使用すること以外にNULLのための他の使用例です。私は解決策を見つけるべきですか? 問題が発生する可能性があるNULLを持たないことの本当に重要な意味はありますか?


null許容ポインターを使用して、null許容ポインターをデフォルトにするという概念をお勧めします。 ポインターではなく参照(&)を介してc ++でほとんどこれを行うことができますが、場合によってはかなりひどく厄介になることがあります。

Java / Cの意味では、言語はnullなしで実行できます。たとえば、Haskell(および他のほとんどの関数型言語)には、オプションのnullポインタの概念を提供するだけの事実上の構文である "Maybe"型があります。


Haskellの多分モナドからページを借りて、存在するかもしれないまたは存在しないかもしれない戻り値の場合をどう扱うか? たとえば、メモリを割り当てようとしたが、利用できなかった場合などです。 あるいは、50個のfoosを保持するための配列を作成したが、まだインスタンス化されていないfoos - これらの種類のものをチェックできるようにするには何らかの方法が必要です。

私はあなたがこれらすべてのケースをカバーするために例外を使うことができると思います、しかしそれはプログラマーがtry-catchブロックでそれらの全てをラップなければならないことを意味するのでしょうか? それはせいぜい迷惑でしょう。 あるいは、すべてが独自の値とその値が有効かどうかを示すブール値を返す必要があります。

FWIW、私はなんらかの NULLの概念を持たないプログラムを意識していません - あなたはすべてのCスタイル言語とJavaでNULLを得ました。 PythonはNone 、Scheme、Lisp、Smalltalk、Lua、Rubyはすべてnilです。 VBはNothing使用します。 そしてHaskellには違う種類のnothingnothing

これは、ある言語がある種のnullを絶対に持たなければならないという意味ではありませんが、他のすべての大きな言語がそれを使用しているのであれば、その背後には確かな根拠があります。

一方、軽量のDSLや他の一般的ではない言語しか作成していない場合は、ネイティブデータ型で必要とされていないものがあれば、おそらくnullなしで取得できます。


すぐに思い浮かぶのは、参照渡しパラメータです。 私は主にObjective-Cのコーダなので、こんなことがよく見受けられます。

NSError *error;
[anObject doSomething:anArgumentObject error:&error];
// Error-handling code follows...

このコードの実行後、 errorオブジェクトには、発生したエラーに関する詳細情報がある場合はそれが含まれます。 しかし、エラーが発生しても構いません。

[anObject doSomething:anArgumentObject error:nil];

errorオブジェクトに実際の値を渡していないので、結果は返されません。また、エラーが発生しても解析しなくてもかまいません。

エラーを別の方法で処理していると既に述べたので、この例は実際には当てはまりませんが、重要なのは、参照によって何かを渡したときにどうしますか? それともあなたの言語はそれをしていませんか?


なぜあなたが言語から 'null'の概念を排除したいのか、私にははっきりしません。 アプリで初期化を「遅延的に」行う必要がある場合、どうしますか。つまり、データが必要になるまで操作を実行しないでください。 例:

public class ImLazy {
 public ImLazy() {
  //I can't initialize resources in my constructor, because I'm lazy.
  //Maybe I don't have a network connection available yet, or maybe I'm
  //just not motivated enough.
 }

 private ResourceObject lazyObject;
 public ResourceObject getLazyObject() { //initialize then return
  if (lazyObject == null) {
   lazyObject = new DatabaseNetworkResourceThatTakesForeverToLoad();
  }
 }

 public ResourceObject isObjectLoaded() { //just return the object
  return (lazyObject != null);
 }
}

このような場合、getObject()の値をどのように返すことができますか? 次の2つのうちの1つを考え出すことができます。

宣言内でLazyObjectを初期化するようにユーザーに要求します。 ユーザーはダミーオブジェクト(UselessResourceObject)を入力する必要があります。これには、同じエラーチェックコードをすべて記述する必要があります(if(lazyObject.equals(UselessResourceObject)...)または)。

nullと同じように動作しますが、名前が異なる他の値を使用します。

私が見ることができる限り、どんな複雑な/ OO言語のためにも、あなたはこの機能性、またはそのようなものを必要とします。 null以外の参照型を持つこと(たとえば、メソッドシグネチャ内で、メソッドコード内でnullチェックを実行する必要がないようにすること)は有益かもしれませんが、null機能は、次のような場合に利用できるはずです。それを使ってください。


プログラミング言語でNULLの存在を許可する方法について説明していますが、そのようなNULL参照を参照するリスクも排除した 、Tony HoareによるLtUに関する最近の記事「 Null References:The Billion Dollar Mistake 」があります。 それはとても単純に見えますが、それはとても強力なアイデアです。

更新 :私が読んだ実際の論文へのリンクです。ここでは、Eiffelでの実装について説明していますhttp://docs.eiffel.com/book/papers/void-safety-how-eiffel-removes-null-pointer-dereferencing : http://docs.eiffel.com/book/papers/void-safety-how-eiffel-removes-null-pointer-dereferencing


メソッドがNULLを返すのは便利だと思います。たとえば、検索メソッドが何らかのオブジェクトを返す場合、見つかったオブジェクトを返すことができます。見つからなかった場合はNULLを返すことができます。

私はRubyについて学び始めています。RubyにはNULLに関する非常に興味深い概念があります。 Rubyでは、NULLはNilと呼ばれ、他のオブジェクトと同じように実際のオブジェクトです。 それはたまたまグローバルなシングルトンオブジェクトとして実装されています。 また、RubyにはオブジェクトFalseがあり、ブール式ではNilとFalseの両方がfalseに評価されますが、それ以外のものはすべてtrueと評価されます(たとえば、0でもtrueと評価されます)。


私の考えでは、NULLが一般的に使用される2つのユースケースがあります。

  • 問題の変数に値がありません(Nothing)
  • 問題の変数の値がわかりません(不明)

どちらもよくあることですが、正直なところ両方にNULLを使用すると混乱を招く可能性があります。

注目に値するのは、NULLをサポートしないいくつかの言語はNothing / Unknownの何もサポートしないということです。 たとえば、Haskellは "Maybe"をサポートしています。これには、値またはNothingを含めることができます。 したがって、コマンドは常に値を持つことがわかっているタイプを返す(そして受け入れる)ことも、値がない可能性があることを示すために "Maybe"を返す/受け入れることもできます。