首页 > 解决方案 > 关于将“uint8”转换为“int8”的困惑

问题描述

我想转换uint8int,所以我写了一个 const 0xfc,并尝试使用int8(0xfc)它来转换它。但是代码会引发错误:

package main

import (
    "fmt"
)

func main() {
    a := int8(0xfc)  // compile error: constant 252 overflows int8
    b := a
    fmt.Println(b)
}

但是如果我在赋值后推迟类型转换,代码可以解决。

package main

import (
    "fmt"
)

func main() {
    a := 0xfc
    b := int8(a)  // ok
    fmt.Println(b)
}

我的问题:

标签: go

解决方案


  1. 见:https ://golang.org/ref/spec#Constant_expressions

类型化常量的值必须始终可以由常量类型的值准确表示。以下常量表达式是非法的:

uint(-1)     // -1 cannot be represented as a uint
int(3.14)    // 3.14 cannot be represented as an int
int64(Huge)  // 1267650600228229401496703205376 cannot be represented as an int64
Four * 300   // operand 300 cannot be represented as an int8 (type of Four)
Four * 100   // product 400 cannot be represented as an int8 (type of Four)
  1. 见: https ://blog.golang.org/constants

并非所有整数值都适合所有整数类型。可能会出现两个问题:值可能太大,或者它可能是分配给无符号整数类型的负值。例如,int8 的范围是 -128 到 127,因此该范围之外的常量永远不能分配给 int8 类型的变量:
var i8 int8 = 128 // Error: too large.
类似地,uint8,也称为 byte,范围是 0 到 255,因此大的或负的常量不能分配给一个 uint8:
var u8 uint8 = -1 // Error: negative value.
这种类型检查可以发现像这样的错误:

    type Char byte
    var c Char = '世' // Error: '世' has value 0x4e16, too large. 

如果编译器抱怨你使用了一个常量,那么它很可能是一个像这样的真正的错误。


我的实际需求是在解析二进制文件时将 a 转换byte为。int32我可能会遇到常量 byte 0xfc,应该在将其转换为int8之前将其转移到 ,int32并考虑符号。

是的,这是要走的路:


    var b byte = 0xff
    i32 := int32(int8(b))
    fmt.Println(i32) // -1

推荐阅读