Go语言学习之路(第一天)数据类型

1.第一个Go程序

package main

import "fmt"

func main() {
	fmt.Println("hello,world")
	fmt.Println("你好")
}

   第一行:每个Go源代码文件的开头都是一个package声明,表示该Go代码所属的包。Go语言中是通过包来对代码进行管理的。那么什么是包呢?我通过一个例子来解释一下包的概念。例如:有一家公司叫"京东",该公司有一个项目叫"京东网上商城",该项目下面有管理"客户信息"的代码,另外一家公司叫"淘宝",该公司也有一个项目叫"淘宝网上商城",该项目下面也有管理"客户信息"的代码,我开发的"客户管理软件",既要用到"京东"的客户信息管理代码,也要用到"淘宝"的客户信息管理代码,为了能够很好的区分,我们在使用时必须写清楚,客户的信息管理代码到底是来自哪个商城,所以我可以这样写 import "京东",表示所使用的"客户信息代码"是来自"京东"的,那么"京东"就是一个标识,也就是包。所以说,包就是一个标识,标志着着你写的Go代码来自哪,这样代码管理非常清晰,使用也非常方便。

  不管你创建多少个包,要想让程序运行,必须包含一个main包。如果缺少该包,程序是无法运行的。

  第三行代码:import表示导入,"fmt"是包名。不管是使用我们自己定义的包还是Go自带都是通过import导入的,"fmt"是Go自带的包,该包包含了怎样将信息打印在电脑屏幕上。注意包名要用""表示。

  第五行代码:表示程序的入口,程序就是从该位置开始执行的,就像是教室的门口一样,注意该行代码是固定的写法,func 与main之间必须有空格,同时main后面必须带小括号,后面的一对大括号表示要完成的具体工作,也就是完成具体任务的代码必须写在一对大括号内。func表示后面跟着的main是一个函数,函数必须有一对小括号。什么是函数呢?现在大家可以先理解与我们在数学中学到的函数是一样的,都是实现某个具体的功能,例如我们学习的三角函数等。Main函数实现的就是入口功能。再次强调一下,Go语言中的函数前面必须加上func这个单词,而且函数名称后面必须跟一对小括号。

   第六行代码:就是使用了fmt包(注意具体使用的时候不需要加上双引号)中的Println函数,将要"hello,world" 打印在屏幕上。这行代码要注意的是,fmt包与Println函数之间是用.(点连接的),该点是在半角输入法状态下输入,同时Println函数第一个字母P是大写的,不能写成小写,也就是说Go语言是区分大小写的,有很多同学在这里容易出错。将要输出的信息写在Println函数的括号内(注意括号也是在半角状态下输入的),并且用双引号包裹起来(双引号也是半角状态下输入的)。

2.变量

2.1 什么是变量

  所谓的变量简单的理解就是计算机用来存储数据的。我们可以理解变量就像我们去超市买商品时用到的购物车,我们先将商品从货架上拿下来,放到购物车中,结账时在从购物车中取出商品。计算机通过变量来保存数据实际上将数据存储到计算机的内存中,这里我们可以画一个图给大家理解一下。

  计算机将内存划分成不同的区域,数据就是存储在这些区域中,那么怎样从这些区域中将数据取出来呢?计算机将每块区域都加上了一串数字,作为编号。通过该编号就可以将数据取出来了,但是问题是,这一串数字对我们程序员来说是非常难记忆的,

为了解决这个问题,我们可以通过变量的方式来表示存储的数据,如下图:

  我们给每个存储区域加上了Number1,Number2,Name等符号,这样通过这些符号来存储数据,然后通过这些符号取出数据就非常容易,方便了。这些符号就是变量。

2.2 变量类型

  我们现在理解了变量可以用来存储数据,但是我们要存储的数据类型是各种各样的,例如:整数,小数,文本等等。所以我们必须在定义变量时就要告诉计算机,定义的变量存储是什么类型的数据。那么在内存中就可以根据不同的类型来开辟不同的存储空间。

  生活中关于“类型“的例子:

2.3 变量的定义和使用

  所谓声明变量就是创建一个变量,并且指定该变量存储什么类型的数据。

  Go语言引入了关键字var,而类型信息放在变量名之后。

  定义变量的格式是:var 变量名 数据类型 = 值。

  在定义变量时也可以先声明变量,然后再赋值,格式是:var 变量名 数据类型,此时只是声明了此变量;变量名 = 值,此时是为变量赋值(当只声明变量时,整型的变量的初始值是0;字符串类型的变量初始值是空字符串)。

  示例如下:

package main

import "fmt"

func main() {
	//变量的定义和使用
	//变量定义格式
	//var 变量名 数据类型(声明)
	//var 变量名 数据类型 = 值 (定义)

	//int 表示的是整型 可以存储整数
//定义 var a int = 100 fmt.Println(a)
//修改变量的值 a = 123 fmt.Println(a) //声明 var b int
     //赋值 b = 10
     //使用 fmt.Println(b) }

   结果如下:

64
128
10

2.4 自动推导类型

  在给变量赋值时,我们感觉非常麻烦,有没有更简单的给变量赋值的方式,我们可以使用自动推导类型,自动推导类型就是根据值的类型决定变量的数据类型。

  格式是:变量名 := 值

  具体示例如下:

package main

import "fmt"

func main() {

	//var a int = 10
	//自动推导类型(根据值来确定变量的类型)
	//变量名:=值
	a := 10   //int
	b := 3.14 //float64

	fmt.Println(a)
     //通过自动推导类型定义的浮点型数据,数据类型都是float64 fmt.Println(b) //通过格式化打印数据类型 //%T 是一个占位符 表示输出一个数据对应的类型 fmt.Printf("%T", a) fmt.Println() fmt.Printf("%T", b) }

   结果如下:

10
3.14
int
float64
func main() {

	//var a string = "你好"
	//通过自动推导类型创建字符串
	a := "你好" //创建变量
	a = "我不好" //赋值

	fmt.Println(a)
	fmt.Printf("%T", a)

}

  结果如下:

我不好
string

   所谓自动推导类型,就是不用通过var 声明变量,不用指定类型,直接在变量名后面跟":"号,同时完成赋值。那么Go会根据所赋的值自动推导出变量的类型。如果给变量赋值为小数,那么该变量的类型为小数类型(浮点)。

   

2.5 多重赋值和匿名变量

  我们给变量赋值,可以采用自动推导的方式,如果想一次使用自动推导的方式,给多个变量赋值,应该怎样实现呢?

  var格式定义:var 变量名1 变量名2 ..... = 值1 值2 .......

  自动推导类型:变量名1 变量名2 ..... := 值1 值2 .......

  具体如下:

package main

import "fmt"

func main() {

	//多重赋值
	//定义多个变量
	//var a, b, c int = 10, 20, 30

	//自动推导类型创建多个变量
	//a, b, c := 10, 20, 30

        //自动推导类型创建多个不同类型的变量
	a, b, c := 10, 3.14, "hello"

	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)

	//\n 转义字符  表示换行
	fmt.Printf("%T\n", a)
	fmt.Printf("%T\n", b)
	fmt.Printf("%T\n", c)
}

  结果如下:

10
3.14
hello
int
float64
string  

  由于在Go语言中,你定义的变量必须都要使用,如果定义了但不用就会报错。但有些变量后面确实不用,就可以使用匿名变量。

  _:匿名变量,丢弃数据不进行处理,匿名变量配合函数返回值使用才有价值

func main() {
	//匿名变量
	//_匿名变量  在后面学习中涉及到函数多个返回值时 使用匿名变量
	a, _, _ := 10, 20, 30

	fmt.Println(a)
	//fmt.Println(_)//error 匿名变量数据不能打印	
}

 2.6 数据交换 

  变量名1,变量名2 = 变量名2,变量名1

  这里根Python里是一样的。

  具体如下:

package main

import "fmt"

func main() {
	a := 10
	b := 20

	a, b = b, a

	fmt.Println(a)
	fmt.Println(b)
}

  结果如下:

20
10

2.7 输出格式 

  根据前面的内容,我们看到了三种输出方式:

  fmt.Println("hello"):输出换行

  fmt.Print("hello"):输出不换行

  fmt.Printf("%s\n", "hello"):格式化输出,也不换行

  具体如下:

func main() {
	//打印并换行
	fmt.Println("hello")
	//打印但不换行
	fmt.Print("hello")
	fmt.Print("world")
}

   结果如下:

hello
helloworld
func main() {
	a, b, c := 3, 4.1426, "你瞅啥"

	//\n是一个占位符,表示输出换行
	fmt.Printf("%d\n", a)
	fmt.Printf("%.3f\n", b)
	fmt.Printf("%s\n", c)
}

  结果如下:

3
4.143
你瞅啥

 2.8 输入格式

  前面我们所写的所有的程序,都是直接给变量赋值,但是很多情况下,我们希望用户通过键盘输入一个数值,存储到某个变量中,然后将该变量的值取出来,进行操作。我们日常生活中也经常用到输入的场景:

  咱们在银行ATM机器前取钱时,肯定需要输入密码,对不?

  那么怎样才能让程序知道咱们刚刚输入的是什么呢??

  大家应该知道了,如果要完成ATM机取钱这件事情,需要先从键盘中输入一个数据,然后用一个变量来保存,是不是很好理解啊!

  那么我们Go语言怎样接收用户的键盘输入呢?如下:

func main() {
	var username string
	var passwd string
	fmt.Print("用户名:")
	fmt.Scanf("%s", &username)
	fmt.Print("密码:")
	fmt.Scanf("%s", &passwd)

	fmt.Println(username)
	fmt.Println(passwd)
}

  在Go中我们用到了“fmt”这个包中的Scanf()函数来接收用户键盘输入的数据。当程序执行到Scanf()函数后,会停止往下执行,等待用户的输入,输入完成后程序继续往下执行。在这里重点要注意的是Scanf()函数的书写格式,首先也要用“%s”,来表示输入的是一个字符串,输入完整数后存储到变量username中,注意这里username,变量前面一定要加上“&”符号,表示获取内存单元的地址(前面我们说的内存存储区域的编号),然后才能够存储。

   还有另外一种获取用户输入数据的方式,如下

func main() {
	var a int
	//&,取地址运算符 引用运算符
	//fmt.Scan是一个阻塞时的请求
	fmt.Scan(&a)
	fmt.Println(a)
	//取出变量对应的内存地址
	fmt.Println(&a)
	fmt.Printf("%p\n", &a)
}

  通过Scan函数接收用户输入,这时可以省略掉%d,这种写法更简单。

三.基本数据类型

  前面我们写的程序中,用到的变量的类型都是整型,但是在我们GO语言中,还有很多其它的类型。

类型

名称

长度

零值

说明

bool

布尔类型

1

false

其值不为真即为假,不可以用数字代表true或false

byte

字节型

1

0

uint8别名

int, uint

整型

-

0

有符号32位或无符号64位

int8

整型

1

0

-128 ~ 127 

uint8

整型

1

0

0 ~ 255 

int16 

整型

2

0

-32768 ~ 32767,

uint16

整型

2

0

0 ~ 65535

int32

整型

4

0

-2147483648 到 2147483647

uint32

整型

4

0

0 到 4294967295(42亿)

int64

整型

8

0

-9223372036854775808到92233720368547758070 

uint64

整型

8

0

到 18446744073709551615(1844京)

float32

浮点型

4

0.0

小数位精确到7位

float64

浮点型

8

0.0

小数位精确到15位

string

字符串

 

""

utf-8字符串

3.1 布尔类型

  在计算机中,我们用什么数据类型来表示一句话的对错,例如:在计算机中描述张三(20岁)比李四(18)小,这句话的结果?

  布尔类型的变量取值要么是真(true),要么是假(false),用bool关键字来进行定义。示例如下:

func main() {
	//var a bool
	//a = true

	a := true
	fmt.Println(a)
	fmt.Printf("%T\n", a)
	//%t 是一个占位符,表示输出一个布尔类型的数据
	fmt.Printf("%t\n", a)
}

   结果如下:

true
bool
true

  布尔类型主要用于条件判断

3.2 整型

func main() {
	var a int = -127
	//uint,表示无符号整型数据,只能存储大于0的整数
	var b uint = 128

	fmt.Println("a:", a)
	fmt.Println("b:", b)
}

 结果如下:

a: -127
b: 128

 当一个整形数据达到了区间的最值时,再进行操作时就会发生变化

var a int8 = -128
	var b int8 = 127
	a -= 1
	b += 1

	//数据溢出
	//如果数据达到了区间的最值时,再操作就会发生变化(物极必反)
	fmt.Printf("a:%d\n", a)
	fmt.Printf("b:%d\n", b)

 结果如下:

a:127
b:-128

 3.3 浮点型

  浮点型就是小数类型,在Go中分为分float32和float64两种浮点型,用float64就可以。通过自动推导类型创建的浮点型数据 ,数据类型就是float64。

func main() {
	//单精度浮点型,小数位数有效为7位
	var a float32 = 3.44
	//双精度浮点型,小数位数有效为15位
	var b float64 = 3.44
	//建议在开发中使用float64代替float32

	//自动推导类型创建浮点型,默认为float64
	c := 3.14

	fmt.Println(a)
	fmt.Println(b)

	fmt.Printf("%T\n", c)

	fmt.Printf("%.20f\n", a)
	fmt.Printf("%.20f\n", b)

}

   结果如下:

3.44
3.44
float64
3.44000005722045898438
3.43999999999999994671

 3.4字符类型

  所谓字符类型是用单引号括起来的单个字符,关于字符的定义使用如下:

func main() {
	//var 变量名 byte = '',字符用''表示,字符串用""表示
	//每个字符都对应有一个ACSII值
	var ch byte = 'a'
	var ch2 byte = 97

	//转义字符
	var xh byte = '\v'

	//在使用fmt.Println输出一个字符时,会得到对应的ACSII值
	fmt.Println(ch)
	fmt.Println(ch2)
	fmt.Println(xh)

	//%c,是一个占位符,表示一个字符,想要输出字符时,需要用fmt.Printf
	fmt.Printf("%c\n", ch)
	fmt.Printf("%c\n", ch)
} 

  结果如下:

97
97
11
a
a

  这里定义了,ch是一个字符类型,赋值却是一个整数97,打印的结果是小写字符’a’。

  原因是:计算机不能直接存储字符类型,只能转成数字存储,但是为什么小写字符‘a’,对应的整数是97呢?因为,计算机是根据’ASCII’码来存储

  附:转义字符:

  字符除了我们常见的字符‘a’,字符’b’等等以外,还有一些特殊的字符,例如前面用到的’\n’, 它的作用是什么?换行,不会在屏幕上输出具体的内容。这种字符我们称为转义字符(具有特殊含义),那么除了’\n’字符以外,还有哪些是我们以后编程中经常用到的转义字符呢?

  \":表示一个英文半角的双引号

  \t:表示一个tab键的空格(可以用来对输出的内容进行排版)

  \\:表示一个\(主要用在表示磁盘目录上,后面学到文件操作时,经常要根据磁盘目录获取文件然后进行读取,写入等操作)

 3.5 字符串类型

  用单引号括起来的单个字符是字符类型,用双引号括起来的字符是字符串类型。 

  字符串的定义如下:

func main() {
	//var a string = "h"
	a := "h"
	fmt.Println(a)
	//%s 是一个占位符,表示输出一个字符串类型的变量
	fmt.Printf("%s\n", a)
	//%T 是一个占位符,表示输出一个变量的数据类型
	fmt.Printf("%T\n", a)
} 

  结果如下:

h
h
string

  

  字符串的拼接和比较如下(算术运算符和关系运算符会在后面讲到),两个字符串相加表示的是字符串拼接

func main() {
	str1 := "大哥"
	str2 := "你好"

	//字符串拼接
	fmt.Println(str1 + str2)
	//字符串比较
	fmt.Println(str1 == str2)
}

   结果如下:

大哥你好
false

 3.6 字符串和字符的关系

  用单引号括起来的单个字符是字符类型,用双引号括起来的字符是字符串类型。  

  具体关系由下方代码进行展示:

func main() {
	ch := 'a'
	//字符串"a"存储了两个字符:'a'和'\0'(\0是一个转义字符,表示字符串的结束标示)
	str := "a"

	fmt.Println(ch)
	fmt.Println(str)

	//一个字符如果不想输出ASCII值,就需要用 %c 占位符
	fmt.Printf("%c\n", ch)
	fmt.Printf("%s\n", str)

	str1 := "你好"
	//len():计算字符串中字符的个数,\0之前的字符是有效字符
	//在go语言中,一个汉字占3个字符
	fmt.Println(len(str))
	fmt.Println(len(str1))
}

  结果如下:

97
a
a
a
1
6

 3.7 占位符的使用

  我们前面在输出与输入字符串类型,字符类型,整型等都指定了对应的格式化,那么go语言中还有哪些格式化呢?

格式

含义

%%

一个%字面量

%b

一个二进制整数值(基数为2),或者是一个(高级的)用科学计数法表示的指数为2的浮点数

%c

字符型。可以把输入的数字按照ASCII码相应转换为对应的字符

%d

一个十进制数值(基数为10)

%f

以标准记数法表示的浮点数或者复数值

%o

一个以八进制表示的数字(基数为8)

%p

以十六进制(基数为16)表示的一个值的地址,前缀为0x,字母使用小写的a-f表示

%q

使用Go语法以及必须时使用转义,以双引号括起来的字符串或者字节切片[]byte,或者是以单引号括起来的数字

%s

字符串。输出字符串中的字符直至字符串中的空字符(字符串以'\0‘结尾,这个'\0'即空字符)

%t

以true或者false输出的布尔值

%T

使用Go语法输出的值的类型

%x

以十六进制表示的整型值(基数为十六),数字a-f使用小写表示

%X

以十六进制表示的整型值(基数为十六),数字A-F使用小写表示

  整型占位符代码如下:

//int
func main1401() {
	//%%,表示字面%
	fmt.Printf("35%%\n")

	a := 123
	//%b,表示输出一个数的二进制格式(0-1)
	fmt.Printf("%b\n", a)
	//%o,表示输出一个数的八进制格式(0-7)
	fmt.Printf("%o\n", a)
	//%x %X,表示输出一个数的十六进制(0-9,Aa-Ff)
	fmt.Printf("%x\n", a)
	fmt.Printf("%X\n", a)
	//%d,表示输出一个数的十进制格式
	//%nd,整体数据为n位,如果不足n位则在前面补空格
	//%-nd,整体数据为n位,如果不足n位则在后面补空格
	//%0nd,整体数据为n位,如果不足n位则在前面补上0
	fmt.Printf("===%d===\n", a)
	fmt.Printf("===%5d===\n", a)
	fmt.Printf("===%-5d===\n", a)
	fmt.Printf("===%05d===\n", a)
}

   结果如下:

35%
1111011
173
7b
7B
===123===
===  123===
===123  ===
===00123===

  浮点型占位符代码如下:

//float
func main1402() {
	a := 3.1415926

	//%f,是一个占位符,表示输出一个浮点型数据,默认保留6位有效数字,会四舍五入
	//%.nf,表示小数点后保留n位,会对n+1位进行四舍五入
	//%m.nf,表示整体数据为m位,小数点后保留n位,.占一位,如果不足m位则在前面补空格
	fmt.Printf("%f\n", a)
	fmt.Printf("%.2f\n", a)
	fmt.Printf("%6.3f\n", a)
}

   结果如下:

3.141593
3.14
 3.142

  字符和字符串占位符代码如下:

//byte和string
func main() {
	ch := 'a'
	str := "a"

	//一个字符想要输出字符格式,就需要用 %c 占位符,否则就会输出对应的ASCII值
	fmt.Printf("%c\n", ch)
	fmt.Printf("%s\n", str)

	//%q,是一个占位符,表示输出带双引号的字符串或字符切片
	fmt.Printf("%q\n", str)
}

   结果如下:

a
a
"a"

  布尔类型和数据类型代码如下:

//bool和变量的数据类型
func main() {
	a := true

	fmt.Printf("%t\n", a)
	fmt.Printf("%T\n", a)

	//%p,是一个占位符,表示输出一个数据对应的内存地址
	//&:取地址符,可以得到变量对应的内存地址
	fmt.Printf("%p\n", &a)
}

   结果如下:

true
bool
0xc000016048

猜你喜欢

转载自www.cnblogs.com/dacaigouzi1993/p/10915157.html