Golang 中的类型转换

2023-11-29

我正在阅读以下文章:https://www.ribice.ba/golang-enums/

代码示例之一中定义了一个函数:

func (lt *LeaveType) UnmarshalJSON(b []byte) error {
    // Define a secondary type to avoid ending up with a recursive call to json.Unmarshal
    type LT LeaveType;
    var r *LT = (*LT)(lt);
    err := json.Unmarshal(b, &r)
    if err != nil{
        panic(err)
    }
    switch *lt {
    case AnnualLeave, Sick, BankHoliday, Other:
        return nil
    }
    return errors.New("Inalid leave type")
}

语法是什么var r *LT = (*LT)(lt);在这个例子中做什么?


Go技术上没有casts反而转换。显式转换的语法是T(x) where T是某种类型并且x是可转换为该类型的某个值。看Go 规范中的转换了解详情。

从函数的声明中可以看出:

func (lt *LeaveType) UnmarshalJSON(b []byte) error {

lt本身有类型指向LeaveType and UnmarshalJSON is a 接收函数对于类型*LeaveType. The encoding/json当包想要设置的变量具有类型时,包将调用这样的函数来解码输入 JSONLeaveType (or *LeaveType- 该包将创建LeaveType在这种情况下变量本身)。

正如代码中的注释所说,代码的作者现在希望拥有encoding/json代码解组 JSONas if没有函数UnmarshalJSON。但有is一个函数UnmarshalJSON,所以如果我们只是调用encoding/json没有一点欺骗的代码,encoding/json只会再次调用该函数,导致无限递归。

通过定义一个new type LT其内容与现有类型完全相同LeaveType,我们最终得到一个新类型does not具有接收功能。调用encoding/json在此类型的实例(或指向该类型的指针)上won't打电话给*LeaveType接收器,因为LT是一种不同的类型,尽管它的contents完全匹配。

我们可以这样做:

func (lt *LeaveType) UnmarshalJSON(b []byte) error {
    type LT LeaveType
    var r LT
    err := json.Unmarshal(b, &r)
    if err != nil {
        panic(err)
    }
    // ...
}

这将填写r,其大小和形状与任何LeaveType多变的。然后我们就可以使用填好的r to set *lt:

*lt = LeaveType(r) // an ordinary conversion

之后我们可以像以前一样继续使用*lt作为值。但这意味着UnmarshalJSON必须设置一个临时变量r,然后我们必须将其复制到其最终目的地。为什么不相反,设置一些东西,以便UnmarshalJSON填充目标变量,但是使用我们选择的类型?

这就是这里的语法for。这不是shortest版本:正如 Cerise Limón 所指出的,有一种更短的拼写方式(并且通常首选较短的拼写)。第一组括号(*LT)(lt)需要绑定*—the 指向部分——到LT, as *LT(lt)绑定错误:它的含义与*(LT(lt))这不是我们想要的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Golang 中的类型转换 的相关文章

随机推荐