2015-04-08 3 views
1

Недавно я обнаружил, что какой-то код go работал в тестовой среде, где были некоторые неинициализированные переменные.Golang: Защитные интерфейсы для нулевых типов

Это приводит к панике, в которой была трассировка стека, содержащая некоторый код c вверху.

Есть ли способ, в функциях, чтобы мы могли четко определить структуру, на которую ссылаются, поскольку исполнительный элемент равен нулю? т.е.

func (d *Dog) canBark Bool { 
     //if d is nil, cryptic exception is thrown. 
     //is there a way to defend against this? 
} 

ошибка, которая выбрасывается в

panic: runtime error: invalid memory address or nil pointer dereference 
[signal 0xb code=0x1 addr=0x0 pc=0x4ec83a] 
goroutine 16 [running]: 
runtime.panic(0x9b7400, 0xf7ddf3) 

Кажется, что в ходу, такие более низкие ошибки уровня должно происходить очень редко, может быть, никогда вообще ...

Там может быть способ Golang справиться с nil ссылками, которые не загромождают код слишком много с if/else логикой. Например, в java вы можете обернуть большой сегмент кода в обработчик исключений нулевого указателя.

+2

Напишите тесты для проверки таких панических ситуаций. В не-тестовом коде «паника» - правильная вещь для неправильного кода; так же, как с ошибками, связанными с ошибками, и т. д. –

ответ

4

Вы можете проверить на ноль, а затем делать все:

func (d *Dog) canBark bool { 
    if d == nil { 
     // do something useful, maybe? Like log 
     // a stack trace for debugging later 
     log.Print("Attempt to bark a nil dog!") 
     return false 
    } 
    // do the regular things 
} 
+2

И я бы добавил, что в качестве второй линии защиты многие пакеты предлагают новый конструктор, например. 'dog.New()' или 'animals.NewDog()', что гарантирует правильную инициализацию структуры вместе со всеми ее свойствами. – Zikes

2

Sure:

func (d *Dog) bool { 
    if d == nil { 
     // a nil dog can't bark 
     return false 
    } 
} 

Это вполне возможно использовать методы на нулевой структуры. Тем не менее, интерфейс nil - это еще одна история. Вы не можете защититься от этого, потому что нет типа для вызова метода.

type Barker interface { 
    CanBark() bool 
} 

var dog Barker 
//panics 
dog.CanBark() 

В go, это ошибка программирования для неправильной инициализации структуры данных, и методы могут паниковать. Если значение типа возвращается вам из функции или метода, обычно возвращается значение ошибки, указывающее, можно ли использовать первое значение.

+0

где «dogFace» исходит ... я предполагаю, что это будет ошибка компиляции, не так ли? – jayunit100

+0

@ jayunit100: извините, вырежьте и вставьте ошибку – JimB

Смежные вопросы