Goはnilをレシーバーにメソッドを呼んでもnil pointerで落ちない
Goはヌルポしないという事実に驚愕してしまった
もう言いたいことはタイトルがすべてなのだが、Goはnilからメソッドを呼んでもnil ponterでパニックになったりしない。
以下のGoのプログラムでmain()関数のローカル変数fはnilだが、f.IsNull()などのメソッドを呼んでもパニックにならず結果を返す。
package main import ( "fmt" ) type Foo struct { Name string } func (f *Foo) IsNull() bool { return f == nil } func (f *Foo) Hello() string { return "Hello, world." } func main() { var f *Foo fmt.Println(f.IsNull(), f.Hello(), f) // => true Hello, world. <nil> }
これには驚愕してしまった!
もしかしたら最近の言語は新しいバージョンに変わってヌルポ対策されてヌルチェックが必要なくなったのかと思った。
Pythonで同じことをやってみた
気になってPythonでも試してみた。
class Foo: def is_null(self): return self is None f: Foo = Foo() print(f.is_null()) # False x: Foo = None print(x.is_null())
typeヒントをつけて似たようなことをしたが、当然のようにAttributeErrorが出る。違和感なし。
実行結果
Traceback (most recent call last): File "foo.py", line 12, in <module> print(x.is_null()) AttributeError: 'NoneType' object has no attribute 'is_null'
ちなみにPythonのバージョンは3.7.4だった。
$ python3 -V
Python 3.7.4
まあPythonは型がない言語だから(審議中)こういうところはいい加減なのかもしれない。
Javaでも同じことをやってみた
でもJavaはどうなったのか気になる。
何と言ってもヌルポはJavaが生んだと言っても過言ではないほどヌルチェックばかりやらされた昔の嫌な思い出しかない。
もし新しいJavaでヌルポ対策されていたなら世の中は良くなっていないと誰が言えるであろうか(反語)。
結論から言うと、JavaはおなじみのNullPointerExceptionが出てしまった。
public class Foo { public static void main(String[] args) { System.out.println("Hello, world."); Person p = new Person(); System.out.println(p.isNull()); // => false Person p2 = null; System.out.println(p2.isNull()); // Exception in thread "main" java.lang.NullPointerException // at Foo.main(Foo.java:9) } } class Person { boolean isNull() { return this == null; } }
なーんだ〜〜〜、やっぱりいつものJavaじゃないか〜〜〜〜wwwwww
ちゃんちゃん、世の中甘くないのである。
ちなみにJavaのバージョンはopenjdk12だった。
$ java --version
openjdk 12.0.2 2019-07-16
OpenJDK Runtime Environment (build 12.0.2+10)
OpenJDK 64-Bit Server VM (build 12.0.2+10, mixed mode, sharing)
サンプルコードは↓ここに置いておきました。
https://github.com/oyakata/gooooolang/tree/master/javanullpo
最後までお読みくださりありがとうございました。