今川館

都内勤務の地味OLです

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


最後までお読みくださりありがとうございました。