关于将uint8转换为int8的困惑 [英] confusion about convert `uint8` to `int8`

查看:434
本文介绍了关于将uint8转换为int8的困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将uint8转换为int,所以我写了一个const 0xfc,并尝试使用int8(0xfc)对其进行转换.但是,代码会引发错误:

I want to convert uint8 to int, so I write a const 0xfc, and try to use int8(0xfc) to convert it. However the code raises an error:

package main

import (
    "fmt"
)

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

但是如果我在分配后推迟类型转换,则代码可以解决.

But if I defer the type conversion after assignment, the code can work around.

package main

import (
    "fmt"
)

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

我的问题:

  • 这两个代码之间有什么区别吗?
  • 为什么第一个会引发编译错误?

推荐答案

  1. 请参阅: https://golang.org/ref/spec#Constant_expressions

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

The values of typed constants must always be accurately representable by values of the constant type. The following constant expressions are illegal:

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
  1. see: https://blog.golang.org/constants

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

not all integer values can fit in all integer types. There are two problems that might arise: the value might be too large, or it might be a negative value being assigned to an unsigned integer type. For instance, int8 has range -128 through 127, so constants outside of that range can never be assigned to a variable of type int8:
var i8 int8 = 128 // Error: too large.
Similarly, uint8, also known as byte, has range 0 through 255, so a large or negative constant cannot be assigned to a uint8:
var u8 uint8 = -1 // Error: negative value.
This type-checking can catch mistakes like this one:

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

如果编译器抱怨您使用了常量,则可能是真正的错误.

If the compiler complains about your use of a constant, it's likely a real bug like this.


我的实际需求是在解析二进制文件时将byte转换为int32.我可能会遇到常量字节0xfc,应该在考虑符号的情况下将其转换为int32之前将其传输到int8.

My actual demand is to convert a byte to int32 when parsing a binary file. I may encounter the constant byte 0xfc, and should transfer it to the int8 before converting it to the int32 with the consideration of sign.

是的,这是要走的路:


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

这篇关于关于将uint8转换为int8的困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆