Подтвердить что ты не робот

Как получить сообщение об ошибке в строке в golang?

Я задал этот вопрос - os.Error - строковое значение (Golang), но это не работает в моем случае.

func (t Trans) TicketQty() (intQty int, err string) {
  defer func() {    
    str := recover()
    if(str != nil){     
      err = "an error"
    }
  }()   
  Qty := t.TransObject["qty"].(map[string] interface{})["ticket fv"].(float64)  
  intQty = 10
  return 
}

В этом err мне нужно выдать сообщение об ошибке, например. если логика синтаксического анализа терпит неудачу, она автоматически выдает ошибку. Это ошибка, которую мне нужно поймать. Я показываю это только, например, независимо от исключения времени выполнения, мне нужно поймать его и передать как err в return.

Как это сделать?

4b9b3361

Ответ 1

Используйте errors для создания новых ошибок.

err = errors.New("an error")

Возвращенная ошибка может рассматриваться как строка путем доступа к err.Error() или с помощью функций пакета fmt (например, fmt.Println(err)).

Не используйте recover, если вы действительно не знаете, что делаете. Идиоматично возвращать все ошибки и обращаться с ними, когда они возникают.

См. Обработка ошибок и Go и Отложить, Паника и Восстановление в блоге Go для получения дополнительной информации.

EDIT:

Перечитав свой вопрос, похоже, что вы пытаетесь восстановиться после возможных неудачных типов утверждений. В этом случае рекомендуется использовать идиому "запятая, ок" (упомянутая в ранее связанном разделе документов), которая (слегка перефразируемая, чтобы быть более общей) означает:

"Если утверждение типа терпит неудачу, [переменная-получатель] будет существовать и иметь тип [все, что было заявлено], но оно будет иметь нулевое значение..."

Простой пример для проверки, если interface{} на самом деле является утверждением float64 через тип, и выдает пользовательскую ошибку, если она терпит неудачу (вместо паники):

package main

import (
    "errors"
    "fmt"
)

// assertFloat64 attempts a type assertion to float64.
// It returns a custom error if it fails.
func assertFloat64(n interface{}) error {
    // Type assertion. Is n float64?
    f, ok := n.(float64)
    // If yes,
    if ok {
        // print the result
        fmt.Printf("%f is float64\n", f)
        // and return nil error.
        return nil
    }
    // Else return our custom error
    return errors.New(fmt.Sprintf("could not assert that \"%v\" is float64.\n", n))
}

func main() {
    // Successful
    // 1024.0 is float64
    err := assertFloat64(1024.0)
    if err != nil {
        fmt.Println(err)
    }

    // Failure
    // "foo" isn't float64
    err = assertFloat64("foo")
    if err != nil {
        fmt.Println(err)
    }
}

Будет напечатан:

1024.000000 - float64
не мог утверждать, что "foo" - float64.

Игровая площадка

Ответ 2

Я думаю, что это сделало бы то, что вы хотите:

func (t Trans) TicketQty() (intQty int, err error) {
  defer func() {    
    ex := recover()
    if(ex != nil){     
      // "%v" prints the value of ex
      // for strings, it is the string, for errors .Error() method, for Stringer the .String() etc
      // Errorf returns an error instead of a string
      err = fmt.Errorf("%v", ex)
    }
  }()   
  ... // do your thing
  return
}