Как сравнить errno в Go?

#c #go #cgo

#c #Вперед #cgo

Вопрос:

В Cgo вы не можете получить значение errno напрямую, но вы можете получить его результат после вызова функции, используя двойное возвращаемое значение. например ret, err := C.write(...) . Однако, похоже, что это err просто непрозрачный интерфейс ошибки и его нельзя сравнить с константами errno. Как я могу сделать, например, что-то вроде этого:

 ret, err := C.my_func()
if ret == -1 {
    // error signaled
    if err == C.EAGAIN {
        // do it again
    } else {
        return err
    }
} else {
    ...
}
  

С тех пор этот код не компилируется invalid operation: err == _Ciconst_EAGAIN (mismatched types error and int) . Возможно ли это вообще?

Ответ №1:

Тип ошибки будет syscall.Errno , который вы можете утверждать и сравнивать.

 ret, err := C.my_func()
if errno, ok := err.(syscall.Errno); ret == -1 amp;amp; ok {
    // error signaled
    if errno == C.EAGAIN {
        // do it again
    } else {
        return err
    }
}
  

Комментарии:

1. Это хороший ответ. Однако для всех, кто читает, вы всегда должны проверять возвращаемое значение на -1 (или все, что задокументировано, чтобы сигнализировать об ошибке), а не проверять errno на nil, поскольку нет гарантии, что errno равен нулю в случае успеха. Смотрите utcc.utoronto.ca /~cks/space/блог /программирование/GoCgoErrorReturns

2. @cry0genic: хорошая мысль, я тоже добавлю проверку в пример, хотя, как вы сказали, вам нужно проверить правильное условие на основе обратного сигнала.