Go基本数据类型----布尔类型与数字类型

Go基本数据类型----布尔类型与数字类型

运算符

  下面是 Go 语言中支持的运算符号的优先级排列

Precedence Operator
5 * / % << >> & &^
4 + - | ^
3 == != < <= > >=
2 &&
1 ||
  1. && ​和 || ​操作符有短路行为:如果运算符左边值已经可以确定整个布尔表达式的值,那么运算符右边的值将不再被求值

  2. 对于上表中前两行的运算符,例如 +​ ​运算符还有一个与赋值相结合的对应运算符 +=​,可以用于简化赋值语句。

  3. Go 语言中没有自增与自减运算符,它们被降级为了语句 statement​,并且规定了只能位于操作数的后方,所以不用再去纠结 i++​ ​和 ++i​ ​这样的问题。

    a++ // 正确
    ++a // 错误
    a-- // 正确

    还有一点就是,它们不再具有返回值,因此 a = b++​ ​这类语句的写法是错误的。

  4. 算术运算符 +​、-​、*​ ​和 /​ ​可以适用于整数、浮点数和复数,但是取模运算符 %​ ​仅用于整数间的运算。并且 %​ ​取模运算符的符号和被取模数的符号总是一致的,因此 -5%3​ ​和 -5%-3​ ​结果都是 -2​。

  5. 除法运算符 /​ ​的行为则依赖于操作数是否全为整数,比如 7.0/4.0​ ​的结果是 1.75​,但是 7/4​ ​的结果是 1​。

  6. 一个算术运算的结果,不管是有符号或者是无符号的,如果需要更多的 bit 位才能正确表示的话,就说明计算结果是溢出了,并且超出的高位的 bit 位部分将被丢弃,但不会报错。如果原始的数值是有符号类型,而且最左边的 bit 位是 1 的话,那么最终结果可能是负的,例如 int8​的例子:

    var u uint8 = 255
    fmt.Println(u, u+1, u*u) // "255 0 1"
    var i int8 = 127
    fmt.Println(i, i+1, i*i) // "127 -128 1"
  7. 所有的二元运算符都需要操作数的类型相同,即便是int32​和int64​也不能直接进行加分操作,所以如果想要运行成功只能使用显示的类型转换

    var a int32 = 10
    var b int64 = 20
    d := a + b // invalid operation: a + b (mismatched types int32 and int64)
    c := int64(a) + b // 正确

  ‍

数据类型

布尔类型

类型 描述
bool true ​为真值,false ​为假值,默认值为 false

  在 Go 语言中,布尔型、数字类型和字符串等基本类型都是可比较的,即两个相同类型的值可以用 == !=进行比较,得到布尔类型的结果。此外,整数、浮点数和字符串可以通过大小比较运算(><等)比较大小,结也会得到布尔类型的结果。许多其它类型的值可能是不可比较的,因此也就可能是不可排序的。

var aVar = 10
// 二元运算符进行相等比较
aVar == 5 -> false
aVar == 10 -> true
// 二元运算符进行不等比较
aVar != 5 -> true
aVar != 10 -> false

  除此之外,还有上一部分我们提到的 && ​和 || ​运算符(短路行为),以及一元运算符 !

!T -> false
!F -> true
// 只有两边的值都为 true ,结果才是 true;否则结果为false
T && T -> true
T && F -> false
F && T -> false
F && F -> false
//只有两边的值都为 false ,结果才是 false;否则结果为 true
T || T -> true
T || F -> true
F || T -> true
F || F -> false

在 Go 中,整数 0 并不代表假值,非零整数也不能代表真值,即数字无法代替布尔值进行逻辑判断,两者是完全不同的类型。

  但是我们可以用下面两个函数完成 bool​ 和 int​ 类型的相互转换

// btoi returns 1 if b is true and 0 if false.
func btoi(b bool) int {
if b {
return 1
}
return 0
}
// itob reports whether i is non-zero.
func itob(i int) bool { return i != 0 }

数字类型

  Go 语言支持整型和浮点型数字,并且原生支持复数。

整型

  整型的零值(默认值)为 0

种类 符号 数据类型 类型宽度(bit) 备注
int
int 32 或 64 与计算机系统的位数有关
int8 8
int16 16
int32 32 相当于 32 位系统下的 int 类型
int64 64 相当于 64 位系统下的 int 类型
uint
uint 32 或 64 与计算机系统的位数有关
uint8 8
uint16 16
uint32 32 相当于 32 位系统下的 uint 类型
uint64 64 相当于 64 位系统下的 uint 类型
uintptr 是一个足够大的整数类型,足以容纳任何位数的整数指针(特殊用途)。

int 并没有指定它的位数,说明它的大小,是可以变化的,那根据什么变化呢?

  • 当你在 32 位的系统下,int​和uint​都占用 4 个字节,也就是 32 位。
  • 若你在 64 位的系统下,int​和uint​都占用 8 个字节,也就是 64 位。

出于这个原因,在某些场景下,你应当避免使用int​和uint​,而使用更加精确的int32​和int64

无符号数往往只有在位运算或其它特殊的运算场景才会使用,就像 bit 集合、分析二进制文件格式或者是哈希和加密操作等。它们通常并不用于仅仅是表达非负数量的场合

bit位运算

  位运算只能用于整数类型的变量,且需当它们拥有等长位模式时。

& 位运算 AND
| 位运算 OR
^ 位运算 XOR
&^ 位清空(AND NOT)
<< 左移
>> 右移
  • 按位与 &​:

    在 Go 中, &​ 运算符在两个整型操作数中执行按位 AND​ 操作。AND​ 操作具有以下属性:

    Given operands a, b
    AND(a, b) = 1; only if a = b = 1
    else = 0
  • 按位或 |​:

    |​ 运算符在两个整型操作数中执行按位 OR​ 操作。OR​ 操作具有以下属性:

    Given operands a, b
    OR(a, b) = 1; when a = 1 or b = 1
    else = 0
  • 按位异或 ^​:

    ^​ 运算符在两个整型操作数中执行按位 XOR​ 操作。XOR​ 操作具有以下属性:

    Given operands a, b
    XOR(a, b) = 1; only if a != b
    else = 0
  • 与非 &^​:

    &^​ 运算符在两个整型操作数中执行按位 AND_NOT​ 操作。AND_NOT​ 操作具有以下属性:

    Given operands a, b
    AND_NOT(a, b) = AND(a, NOT(b))
    /* 若b=1 */
    AND_NOT(a, 1) = 0; clears a
    AND_NOT(a, 0) = a;
  • 按位取反 ^​:

    该运算符与异或运算符一同使用,即 m^x​,对于无符号 x​ 使用m=​“全部位设置为 1”,对于有符号 x​ 时使用 m=-1​(全部位也都为1)。

    ^10 = -01 ^ 10 = -11
  • 位左移 <<​ 与 位右移 >>​:

    Go 使用 <<​ 和 >>​ 来表示左移运算符和右移运算符,如下所示:

    Given integer operands a and n,
    a << n; shifts all bits in a to the left n times
    a >> n; shifts all bits in a to the right n times

    注意:左移符每次移动都会将低位右侧补零,相对应,使用右移位操作符进行运算时,每个位均向右方移动,空出的高位补零。因为这个原因,最好用无符号整数运算,这样你可以将整数完全当作一个bit位模式处理。

浮点型

  浮点型的零值(默认值)为0.0

类型 精度位数 类型和描述
float32 小数点后 6 位 IEEE-754 32 位浮点型数,单精度
float64 小数点后 15 位 IEEE-754 64 位浮点型数,双精度

  由于浮点数精确度的缘故,你在使用 ==​ 或者 !=​ 来比较时应当非常小心。

通常应该优先使用 float64​类型,因为float32​类型的累计计算误差很容易扩散,并且float32​能精确表示的正整数并不是很大(译注:因为 float32​ 的有效 bit 位只有 23 个,其它的 bit 位用于指数和符号;当整数大于23bit​能表达的范围时,float32​的表示将出现误差)。一个更重要的原因是math​ 包中所有有关数学运算的函数都会要求接收float64​类型。

  以下是float32​精度不足而引起的判断错误

import "fmt"
var myfloat01 float32 = 100000182
var myfloat02 float32 = 100000187
func main() {
fmt.Println("myfloat: ", myfloat01)
fmt.Println("myfloat: ", myfloat01+5)
fmt.Println(myfloat02 == myfloat01+5)
}
/* 输出结果:
myfloat: 1.00000184e+08
myfloat: 1.0000019e+08
false
*/
复数类型
类型 描述
complex128 64 位实数和虚数
complex64 32 位实数和虚数

  复数使用 re+im i​ 来表示,其中 re​ 代表实数部分,im​ 代表虚数部分,i​ 代表根号负 1。下面我们用两种方法构建复数类型变量:

var c1 complex64 = 5 + 10i
fmt.Printf("The value is: %v", c1)
// 输出: 5 + 10i
re, im := 5.1, 10.1
c := complex(re, im)
fmt.Println(c)
// 输出: 5.1 + 10.1i

  在Go语言中,存在两个内建的函数---- real(c)​ 和 imag(c)​ 可以分别获得相应的实数和虚数部分。

var x complex128 = complex(1, 2) // 1+2i
var y complex128 = complex(3, 4) // 3+4i
fmt.Println(x*y) // "(-5+10i)"
fmt.Println(real(x*y)) // "-5"
fmt.Println(imag(x*y)) // "10"

如果你对内存的要求不是特别高,最好使用 complex128​作为计算类型,因为math​包中相关函数都使用这个类型的参数。

posted @   3381  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示