1

给定以下代码:

iv, err := strconv.ParseInt("18446744073709551448", 10, 64)
fmt.Println(iv)
fmt.Printf("%#v\n", err)
fmt.Printf("%v\n", err)

//Output:
9223372036854775807
&strconv.NumError{Func:"ParseInt", Num:"18446744073709551448", Err:(*errors.errorString)(0x1040a040)}
strconv.ParseInt: parsing "18446744073709551448": value out of range

如何检测到函数因超出 int64 范围而失败?strconv.ParseInt函数返回一个错误类型,但在这种情况下,它实际上是一个strconv.NumError类型,如 所示%#v错误处理和 Go文章提到您可以使用类型断言来检查特定类型的错误,但它没有给出任何示例。我应该使用什么表达式来完成此代码:

if expression {
    uv, err := strconv.ParseUint("18446744073709551448", 10, 64)
}
4

2 回答 2

11

我们有,

包 strconv

var ErrRange = errors.New("value out of range")

ErrRange指示值超出目标类型的范围。

type NumError struct {
        Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat)
        Num  string // the input
        Err  error  // the reason the conversion failed (ErrRange, ErrSyntax)
}

NumError记录失败的转换。

func (e *NumError) Error() string

例如,

package main

import (
    "fmt"
    "strconv"
)

func main() {
    iv, err := strconv.ParseInt("18446744073709551448", 10, 64)
    if err != nil {
        if numError, ok := err.(*strconv.NumError); ok {
            if numError.Err == strconv.ErrRange {
                fmt.Println("Detected", numError.Num, "as a", strconv.ErrRange)
                return
            }
        }
        fmt.Println(err)
        return
    }
    fmt.Println(iv)
}

输出:

检测到 18446744073709551448 值超出范围
于 2015-03-11T03:33:02.993 回答
-1

从返回的错误strconv.ParseInt仅在编译时才知道是某种实现 Error 接口的类型。类型断言允许你坚持它是 astrconv.NumError并直接检查它的字段,但如果你证明是错误的,就有可能引发运行时恐慌:

if err.(*strconv.NumError).Err.Error() == "value out of range" {
    uv, err := strconv.ParseUint("18446744073709551448", 10, 64)
}

一个更灵活的解决方案(但可能对您的目的来说太松散了)是对err.Error()方法执行子字符串匹配:

if strings.Contains(err.Error(), "value out of range") {
    uv, err := strconv.ParseUint("18446744073709551448", 10, 64)
}
于 2015-03-11T03:30:30.363 回答