Непустой интерфейс в runtime представлен структурой iface: два указателя - itab (информация о типе и таблица методов интерфейса) и data (указатель на конкретное значение). Пустой интерфейс interface{} (any) - структура eface: указатель на _type и указатель на data.
На 64-битной платформе интерфейс занимает 16 байт (два слова). При присваивании значения интерфейсу заполняются type и data.
var i io.Reader
var r *bytes.Reader
i = r // itab описывает *bytes.Reader и io.Reader, data = r
Проверка i == nil истинна только когда оба поля нулевые. Если присвоить *T(nil), type уже не nil - интерфейс не nil.