为了账号安全,请及时绑定邮箱和手机立即绑定

斯特里康夫Itoa 不接受 int64 类型的值

斯特里康夫Itoa 不接受 int64 类型的值

Go
繁星点点滴滴 2022-09-26 17:24:14
我正在学习使用 Go 创建 REST API。这就是我被困住的地方。当用户发送创建请求时:从文章的片段中,我需要采取最后一篇文章将 ID(原字符串)转换为整数递增整数并将其转换回字符串并保存文章结构type Article struct {    Id       string  `json:"id"`    Title    string  `json:"title"`    Desc     string  `json:"desc"`    Content  string  `json:"content"`}逻辑如下// get the last id and convert it to integer and increment    lastId, err := strconv.ParseInt(Articles[len(Articles) - 1].Id, 10, 64)    lastId = lastId + 1     if err != nil {        http.Error(w, "Internal Server Error", http.StatusInternalServerError)    }    response := []Article{        {            Id: strconv.Itoa(lastId),// 👈 ERROR            Title:   articleBody.Title,            Desc:    articleBody.Desc,            Content: articleBody.Content,        },    }错误cannot use lastId (variable of type int64) as int value in argument to strconv.Itoa compiler (IncompatibleAssign)
查看完整描述

2 回答

?
白板的微信

TA贡献1883条经验 获得超3个赞

Go 有一个强大的类型系统,因此 Int32 和 Int64 不是兼容的类型。尝试在调用 Itoa 时转换为:lastIdint


    response := []Article{

        {

            Id: strconv.Itoa(int(lastId)),

            Title:   articleBody.Title,

            Desc:    articleBody.Desc,

            Content: articleBody.Content,

        },

    }

编辑:正如@kostix在他的答案中提到的,在转换int类型时要小心溢出(有关详细信息,请参阅他的答案)。

更安全的解决方案是这样的:


newId := int(lastId)

if int64(newId) != lastId {

  panic("overflows!")

}

response := []Article{

            {

                Id: strconv.Itoa(newId),

                Title:   articleBody.Title,

                Desc:    articleBody.Desc,

                Content: articleBody.Content,

            },

 }


查看完整回答
反对 回复 2022-09-26
?
不负相思意

TA贡献1777条经验 获得超10个赞

语言规范

uint大小
为 32 位或 64 位intuint

这意味着,在特定平台/版本的 Go 上,Go 的大小可能与 相同,这就是 Go 不会静默地允许您将 type 的值作为 type 的参数传递的原因。intint32int64int

此外,另一个答案中建议的普通类型转换应该谨慎对待:当你的程序被编译并最终在编译的代码中具有32位大小时会发生什么,并且特定值超出了有符号的32位整数支持的数字范围,例如2,147,483,648?
同样,规范int(lastId)intlastId

在整数类型之间转换时,如果值为有符号整数,则符号扩展到隐式无限精度;否则,它是零扩展。然后将其截断以适合结果类型的大小。例如,如果 ,则 .转换始终产生有效值;没有溢出的迹象。v := uint16(0x10F0)uint32(int8(v)) == 0xFFFFFFF0

因此,代码


var i64 int64 = 2_147_483_648

var i32 = int32(i64)

fmt.Println(i32)

指纹


-2147483648

当此值传递给 时,它将返回“-2147483648” - 很可能不是您所期望的。strconv.Itoa


因此,在健壮的代码中,在执行此类类型转换时应注意,并检查转换后的值是否健全,例如


v := int(lastId)

if int64(v) != lastId {

  panic("ouch!")

}

或者仅仅通过strconv使用最大的方便类型。格式。


查看完整回答
反对 回复 2022-09-26
  • 2 回答
  • 0 关注
  • 91 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信