1. Как работает вызов по nil указателю.2. Как работает семейство fmt.*Print* функций.3. Какие паники можно ловить через recover.Во первых вызов по
nil указателю это вполне корректный код в отличии от, например, Java или C++. До тех пор пока вы не обращаетесь к данным внутри переменной типа, никаких ограничений язык не накладывает. Этим пользуются например в grpc генераторах для создания типов с цепочками методов — даже если переменная nil она все равно может быть рабочей. Единственное но: это работает только с конкретными типами. Для интерфейсов нужно что-бы переменная-интерфейс знала о том какой у нее тип внутри. Да-да тот самый typed nil про который любят спрашивать на собесах иногда имеет реальную применимость. Для второго идем читаем документацию https://pkg.go.dev/fmt#hdr-Format_errors где видим:
If an Error or String method triggers a panic when called by a print routine, the fmt package reformats the error message from the panic, decorating it with an indication that it came through the fmt package. For example, if a String method calls panic("bad"), the resulting formatted message will look like
%!s(PANIC=bad)
The %!s just shows the print verb in use when the failure occurred. If the panic is caused by a nil receiver to an Error or String method, however, the output is the undecorated string, "<nil>".
Т.е. в случае паники
fmt.Println постарается перехватить ее и вывести, что было внутри паники. Исключением являются попытки разыменования по нулевому указателю, вывод паники которой даст <nil>. Почитать исходники можно тут: https://go.googlesource.com/go/+/refs/tags/go1.22.2/src/fmt/print.go#587И наконец третье - перехватить через
recover можно любую панику кроме паники о одновременном чтения и записи (или одновременной записью из разных горутин) в тип map. Вызов runtime.Goexit() перехватить тоже нельзя, т.к. он не является паникой.