1. Introduction
Type conversion points in golangForce type conversionandType AssertionNormal variable types int, float, string can be usedtype(a)This form is used to cast type conversion
2. Type conversion of numbers int and float
1. Integer type int
func TestInt(t *) { var i int = -1 var i8 int8 = int8(i) var i16 int16 = int16(i) var i32 int32 = int32(i) var i64 int64 = int64(i) (i, i8, i16, i32, i64) //-1 -1 -1 -1 -1 var n int = 1111111 var n8 int8 = int8(n) var n16 int16 = int16(n) var n32 int32 = int32(n) var n64 int64 = int64(n) (n, n8, n16, n32, n64) //1111111 71 -3001 1111111 1111111 }
We found that when converting n to int8 and int16, an error occurred. Why is this happening?
In the case that the int type is the default 64 bits on the mac.
int8 represents an integer value between -128 and 127 (8 bits)
int16 represents the integer value between -32768 and 32767 (16 bits)
The ranges they can store are different, and if they exceed a certain type of range, they will make an error.
2. Positive integer type uint
func TestUint(t *) { var i uint = 1 var i8 uint8 = uint8(i) var i16 uint16 = uint16(i) var i32 uint32 = uint32(i) var i64 uint64 = uint64(i) (i, i8, i16, i32, i64) //1 1 1 1 1 var u uint = 1111111 var u8 uint8 = uint8(u) var u16 uint16 = uint16(u) var u32 uint32 = uint32(u) var u64 uint64 = uint64(u) (u, u8, u16, u32, u64) //1111111 71 62535 1111111 1111111 }
Data conversion within the type range is correct, and conversion outside the range is wrong.
3. Cases between int and uint
func TestInt2(t *) { var i int = -1 var i8 uint8 = uint8(i) var i16 uint16 = uint16(i) var i32 uint32 = uint32(i) var i64 uint64 = uint64(i) (i, i8, i16, i32, i64) //-1 255 65535 4294967295 18446744073709551615 var n int = 1 var n8 uint8 = uint8(n) var n16 uint16 = uint16(n) var n32 uint32 = uint32(n) var n64 uint64 = uint64(n) (n, n8, n16, n32, n64) //1 1 1 1 1 var u int = 1111111 var u8 uint8 = uint8(u) var u16 uint16 = uint16(u) var u32 uint32 = uint32(u) var u64 uint64 = uint64(u) (u, u8, u16, u32, u64) //1111111 71 62535 1111111 1111111 }
We found that when each type has different ranges, there will still be a big mistake if the conversion is not careful.
4. Cases between float32 and float64
func TestFloat(t *) { var f32 float32 = 333.333 var f64 float64 = float64(f32) (f32, f64) //333.333 333.3330078125 //Everything is within its own scope var fl64 float64 = 333.333 var fl32 float32 = float32(fl64) (fl64, fl32) //333.333 333.333 //Large type range exceeds small type range var flo64 float64 = 33333333333333333.333 var flo32 float32 = float32(flo64) (flo64, flo32) //333.333 333.333 }
First, we judge the difference between float32 and float64, because the memory size is different, resulting in different accuracy and range.
- float32 and float64 are converted to each other because the accuracy is different, resulting in data differences
- float32 and float64 are converted to each other because the range is different, resulting in data differences
5. Float and int convert each other
func TestFloatInt(t *) { var i int = 333 var f32 float32 = float32(i) var f64 float64 = float64(i) (i, f32, f64) //333 333 333 var f float32 = 333.3 var n int = int(f) var n8 int8 = int8(f) var n16 int16 = int16(f) var n32 int32 = int32(f) var n64 int64 = int64(f) (f, n, n8, n16, n32, n64) //333.3 333 77 333 333 333 }
Because it is a Mac system, I am int here as a signed 64-bit integer data type.
type | Number of bits | Valid numbers | Numerical range |
---|---|---|---|
int64 | 64 | -2^63 ( -9,223,372,036,854,775,808) | 2^63-1(+9,223,372,036,854,775,807 ) |
float32 | 32 | 6-7 | -3.410(-38)~3.410(38) |
float64 | 64 | 15-16 | -1.710(-308)~1.710(308) |
Basically, when int is converted to float type, there is no problem as long as it is within range.
When converting float to int, you need to consider that the decimal point will be automatically discarded and the range issue.
3. Conversion of any pointer type and specific pointer type
Note that any pointer type can only be converted into a specific type of pointer type
If converted to int type pointer type *int
The syntax for forced quasi-change is type(a), so it is here (*int)(a), not int(a)!
1. Convert pointer to int pointer type
func TestIntPointer(t *) { //Scenarios where the conversion can be correct within the scope var i int = 100 pi := (&i) //Convert to int related types var n *int = (*int)(pi) var n8 *int8 = (*int8)(pi) var n16 *int16 = (*int16)(pi) var n32 *int32 = (*int32)(pi) var n64 *int64 = (*int64)(pi) (*n, *n8, *n16, *n32, *n64)//100 100 100 100 100 //-------------------------- //Scope exceeds the scope var i2 int = 10000 pi2 := (&i2) //Convert to int related types var nn *int = (*int)(pi2) var nn8 *int8 = (*int8)(pi2) var nn16 *int16 = (*int16)(pi2) var nn32 *int32 = (*int32)(pi2) var nn64 *int64 = (*int64)(pi2) (*nn, *nn8, *nn16, *nn32, *nn64)//10000 16 10000 10000 10000 }
Although this is a pointer, you still need to pay attention to the scope of the specific type.
Otherwise, it will still be wrong to exceed the maximum or minimum value of the type.
2. Convert pointer to struct pointer type
Or type(a), where the a variable is (&a)
type is (*Struct)
The complete expression is (*Struct)((&a))
func TestStruct(t *) { //There is a struct structure S, with two int types: width and height type S struct { wight int height int } s := S{ wight: 5, height: 6, } p := (&s) //{5 6} (s) //Test is converted to T, and there are two int types: w and h in T. type T struct { w int h int } st := (*T)(p) (*st) //{5 6} }
It was found that although the two structures S and T were different, they were converted to the correct value. Why?
Because the memory holdings that the pointer focuses on, whether it is wight in S or w in T, are actually int types and occupy the same memory
So it can be parsed correctly
If we change the type of T to int8 at this time, we will find an error
func TestStruct(t *) { //There is a struct structure S, with two int types: width and height type S struct { wight int height int } s := S{ wight: 5, height: 6, } p := (&s) //{5 6} (s) //Test is converted to T, there are two int8 types w and h in T. type T struct { w int8 h int8 } st := (*T)(p) (*st) //{5 0} }
The first 5 value obtained is that it can be obtained because it is offset 0 in the pointer, and it is just within the range. If = 10000
Then the first one will also be wrong, as follows
func TestStruct(t *) { //There is a struct structure S, with two int types: width and height type S struct { wight int height int } s := S{ wight: 10000, height: 6, } p := (&s) //{10000 6} (s) //Test is converted to T, there are two int8 types w and h in T. type T struct { w int8 h int8 } st := (*T)(p) (*st) //{16 39} }
So we can conclude that if it is a pointer type, as long as the pointers inside are the same, they can be cast to the correct value.
The above is the detailed content of go cast type(a) and data differences caused by range. For more information about go cast type data differences, please pay attention to my other related articles!