Golang教程:(四)类型

原文:https://golangbot.com/types/

这是本Golang系列教程的第四篇。

你可以阅读 Golang教程:(三)变量 来学习有关变量的知识。

下面是 Go 支持的基本类型:

  • bool
  • Numeric Types
    • int8,int16,int32,int64,int
    • uint8,uint16,uin32,uint64,uint
    • float32,float64
    • complex64,complex128
    • byte
    • rune
  • string

bool

bool 类型表示真假值,只能为 truefalse。请运行下面的程序:

package main

import "fmt"

func main() {  
    var a bool = true
    b := false
    fmt.Println("a:",a,"b:",b)
    c := a && b
    fmt.Println("c:",c)
    d := a || b
    fmt.Println("d:",d)
}

这里 a 被赋值为 trueb 被赋值为 false

c 被赋值为 a && b。与操作符(&&)仅在 ab 都为 true 时才返回 true,因此在这里 c 被赋值为 false

或操作符(||)在 ab 中至少有一个为 true 时返回 true。在这里因为 atrue,因此 d 也被赋值为 true译者注:atrue,因此 a || b 的结果为true,因此 dtrue)。我们将会得到如下输出

a: true b: false 
c: false 
d: true 

有符号整型

int8:表示8位有符号整数
size:8 bits
range:-128 ~ 127

int16:表示16位有符号整数
size:16 bits
range:-32768 ~ 32767

int32: 表示32位有符号整数
size: 32 bits
range: -2147483648 ~ 2147483647

int64: 表示64位有符号整数
size: 64 bits
range: -9223372036854775808 ~ 9223372036854775807

int: 根据底层平台(underlying platform)不同,表示32或64位整数。在实际编程中,除非对大小有明确的要求,否则一般应该使用 int 表示整数。
size: 在32位系统下 32 bits,在64位系统下 64 bits
range: 在32位系统下 -2147483648 ~ 2147483647,在64位系统下 -9223372036854775808 ~ 9223372036854775807

package main

import "fmt"

func main() {  
    var a int = 89
    b := 95
    fmt.Println("value of a is","and b is",b)
}

运行上面的程序,输出结果为:

value of a is 89 and b is 95

在上面的程序中,a 的类型指定为 int,而 b 的类型从其初始值(95)推导。上面我们提到,int 的大小在32位系统下是32位,而在64位系统下是64位。下面让我们验证这个描述。

变量的类型可以在 Printf() 函数中通过 %T 格式化指示符(format specifier)来打印。Go的 unsafe 包中提供了一个名为 Sizeof方法,该方法接收一个变量并返回它的大小(byte数)。因为使用 unsafe 包可能会带来移植性问题,因此我们需要小心地使用它,但就本教程的目的而言,我们可以使用它。

下面的程序打印变量 a 和变量 b 的类型和大小。使用 %T格式化指示符打印类型,使用 %d 格式化指示符打印大小。

package main

import (  
    "fmt"
    "unsafe"
)

func main() {  
    var a int = 89
    b := 95
    fmt.Println("value of a is",b)
    fmt.Printf("type of a is %T size of a is %d",unsafe.Sizeof(a)) //type and size of a
    fmt.Printf("\ntype of b is %T size of b is %d",b,unsafe.Sizeof(b)) //type and size of b
}

运行上面的程序,输出如下:

value of a is 89 and b is 95  
type of a is int size of a is 4  
type of b is int size of b is 4

从上面的输出我们可以推断 abint 类型,它们的大小为 32 bits (4bytes)。如果在64位系统上运行上面的程序那么输出会变得不同。在64位系统上,a 和 b 占 64 bits(8bytes)。

无符号整型

uint8: 表示8位无符号整型
size: 8 bits
range: 0 ~ 255

uint16: 表示16位无符号整型
size: 16 bits
range: 0 ~ 65535

uint32: 表示32位无符号整型
size: 32 bits
range: 0 ~ 4294967295

uint64: 表示64位无符号整型
size: 64 bits
range: 0 ~ 18446744073709551615

uint : 根据底层平台不同表示32或64位无符号整型
size : 32位系统下是32 bits,64位系统下64 bits
range :32位系统下 0 ~ 4294967295,64位系统下 0 ~ 18446744073709551615

浮点类型

float32:32位浮点型
float64:64位浮点型

下面的程序演示了整型和浮点数类型:

package main

import (  
    "fmt"
)

func main() {  
    a,b := 5.67, 8.97
    fmt.Printf("type of a %T b %T\n",b)
    sum := a + b
    diff := a - b
    fmt.Println("sum",sum,"diff",diff)

    no1,no2 := 56, 89
    fmt.Println("sum",no1+no2,no1-no2)
}

变量 ab 的类型从它们的初值推导。在这里 ab 都为 float64。(float64是浮点数的默认类型)。我们将 ab 的和赋值给 sum。将 ab 的差赋值给 diff。然后打印 sumdiffno1no2 也是同样的操作。运行上面的程序,输出如下:

type of a float64 b float64  
sum 14.64 diff -3.3000000000000007  
sum 145 diff -33

复数类型

complex64:实部和虚部都是 float32
complex128:实部和虚部都是 float64

通过内置函数 complex 来构造一个包含实部和虚部的复数。它的原型为:

func complex(r,i FloatType) ComplexType

它接收一个实部和一个虚部为参数并返回一个复数类型。实部和虚部应该为同一类型(float32float64)。如果实部和虚部都是 float32,该函数返回一个类型为 complex64 的复数。如果实部和虚部都是 float64,该函数返回一个类型为 complex128 的复数。

复数也可以通过简短声明语法来创建:

c := 6 + 7i 

让我们写一个小程序来了解复数:

package main

import (  
    "fmt"
)

func main() {  
    c1 := complex(5, 7)
    c2 := 8 + 27i
    cadd := c1 + c2
    fmt.Println("sum:",cadd)
    cmul := c1 * c2
    fmt.Println("product:",cmul)
}

在上面的程序中,c1c2 是两个复数。c1 的实部为 5 虚部为 7c2 的实部为 8 虚部为 27c1c2 的和赋值给 caddc1c2 的积赋值给 cmul运行这个程序得到如下输出

sum: (13+34i) 
product: (-149+191i) 

其他数字类型

byteuint8 的别称
runeint32 的别称

我们将在学习 string 类型时详细讨论 byterune

字符串类型

在Go中字符串(String)是 byte 的集合。如果你觉得这个定义没有任何意义也没关系。我们可以暂且假定一个字符串就是一串字符的集合。在后面的教程中我们将通过一整篇的篇幅来介绍字符串的细节。

让我们写一个程序来了解字符串:

package main

import (  
    "fmt"
)

func main() {  
    first := "Naveen"
    last := "Ramanathan"
    name := first +" "+ last
    fmt.Println("My name is",name)
}

在上面的程序中,first 被赋值为 "Naveen"last 被赋值为 "Ramanathan"。字符串可以通过 + 操作符连接在一起。name 被赋值为 first 、空格与 last 三者连接后的结果。运行上面的程序将得到如下输出

My name is Naveen Ramanathan

还有许多操作可应用于字符串。我们将用单独的一篇教程来介绍它们。

类型转换

Go是强类型的语言,没有隐式的类型提升和转换。让我们通过一个例子说明这意味着什么:

package main

import (  
    "fmt"
)

func main() {  
    i := 55      //int
    j := 67.8    //float64
    sum := i + j //int + float64 not allowed
    fmt.Println(sum)
}

上面的代码在C语言中是完全合法的,但是在Go中却不是。i 的类型是 intj 的类型是 float64,将这两个类型不同的数字相加是非法的。运行这个程序将会报错:main.go:10: invalid operation: i + j (mismatched types int and float64)

为了修复这个错误,我们应该将 ij 转换为同样的类型,在这里让我们将 j 转换为 int。通过 T(v)可以将 v 的值转换为 T 类型 。

package main

import (  
    "fmt"
)

func main() {  
    i := 55      //int
    j := 67.8    //float64
    sum := i + int(j) //j is converted to int
    fmt.Println(sum)
}

现在运行上面的程序,可以得到正确的输出结果:122

在赋值时情况也是如此,将一个变量赋值给另一个类型不同的变量时必须显式转型。下面的程序说明了这一点:

package main

import (  
    "fmt"
)

func main() {  
    i := 10
    var j float64 = float64(i) //this statement will not work without explicit conversion
    fmt.Println("j",j)
}

var j float64 = float64(i) 这一行,i 被转换为 float64,然后赋值给 j。当你尝试将 i 不进行转换直接赋值给 j 时,编译器将报错。


感谢阅读。

目录
上一篇:@L_301_15@
下一篇Golang教程:(五)常量

相关文章

程序目录结构 简单实现,用户登录后返回一个jwt的token,下次请求带上token请求用户信息接口并返回信息...
本篇博客的主要内容是用go写一个简单的Proof-of-Work共识机制,不涉及到网络通信环节,只是一个本地的简...
简介 默克尔树(MerkleTree)是一种典型的二叉树结构,其主要特点为: 最下面的叶节点包含存储数据或其...
接下来学习并发编程, 并发编程是go语言最有特色的地方, go对并发编程是原生支持. goroutine是go中最近本...
先普及一下, 什么是广度优先搜索 广度优先搜索类似于树的层次遍历。从图中的某一顶点出发,遍历每一个顶...
第一天: 接口的定义和实现 第二天: 一. go语言是面向接口编程. 在学习继承的时候说过, go语言只有封装,...