Go Web编程实战(3)----数据类型

2023-11-17

前言

Go语言数据类型包括布尔型、数字类型、字符串类型、复合类型这4种。其中复合类型又分为:数组类型、切片类型、Map类型以及结构体类型。

布尔型

与其他编程语言一样,Go语言的布尔型只可以是true或者false。

下面,我们来举例说明使用方式:

var x int=100
fmt.Println(x==100)
fmt.Println(x!=100)

需要特别注意的是,Go语言对于值之间的比较有非常严格的限制,只有2相同类型的值才可以进行比较。如果值是接口,则它们必须实现相同的接口。如果其中一个值是常量,则另外一个值可以不是常量,但是类型和该常量必须相同。如果以上条件都不满足,则必须将其中一个值的类型转换为和另一个值相同的类型,才可以进行比较。

在Go语言中,and是 &&;or 是 ||。布尔值也不会被显式的转换为0或1,也不能被强制转换成整型。如果你想把布尔型转换为数字0或1,需要这样写:

func main() {
	var x int=100
	fmt.Println(boolToInt(x==100))
	fmt.Println(boolToInt(x!=100))
}

func boolToInt(b bool) int{
	if b{
		return 1
	}
	return 0
}

数字类型

Go语言支持非常多的数字类型,为了让大家更加明了,博主专门列出了一张表格供大家参考。

类型 描述 范围
uint8 无符号8位整型 0~255
uint16 无符号16位整型 0~65535
uint32 无符号32位整型 0~4294967295
uint64 无符号64位整型 0~18446744073709551615
int8 有符号8位整型 -128~127
int16 有符号16位整型 -32768~32767
int32 有符号32位整型 -2147483648~2147483647
int64 有符号64位整型 -9223372036854775808~9223372036854775807
float32 IEEE-754 32位浮点数
float64 IEEE-754 64位浮点数
complex32 32位实数和虚数
complex64 64位实数和虚数
byte 和uint8等价
rune 和int32等价
unit 32位或64位无符号整型
int 32位或64位有符号整型
uintptr 无符号整型,用于存放一个指针

需要注意的是,在32位操作系统上,int和uint均使用32位(4个字节);在64位操作系统上,它们均使用64位(8个字节)。

字符串类型

在Go语言中,字符串是由单个字节连接起来的,字节使用的是UTF-8编码来表示Unicode文本。由于该编码占用字节长度的不确定性,字符串也会根据需要占用1~4byte。

Go语言这样做,不仅减少了内存和硬盘空间的占用,而且也不用像其他语言那样需要对使用UTF-8字符集的文本进行编码和解码。

下面,我们先来看一段代码:

str1 :="\"liyuanjing\"" +
		"str1"
str2 :="liyuanjing\n"
fmt.Print(str2)
fmt.Print(str1)

如果大家运行上面这段代码,就会发现str2输出完成之后也会换行,要知道我们这里用的Print,并不是Println。所以,可以得出结论,Go语言字符串支持“\”转义,但转义字符会按意义默认输出。同时,字符串也支持换行链接。

另外,Go语言的字符串,你可以默认看作一个数组,它可以通过“[]”写入索引来获取单个的字符。下面,我们来举一个例子。

str1 :="liyuanjing"
//获取字符串索引1(位置2)的字符ASCII编码
fmt.Println(str1[1])
//获取字符串索引1(位置2)的字符
fmt.Println(string(str1[1]))
//获取字符串索引0到2的字符(不包括2)
fmt.Println(str1[0:2])
//获取字符串索引6开始的所有的字符
fmt.Println(str1[6:])
//获取字符串索引0到2的字符(不包括2)
fmt.Println(str1[:2])
//获取字符串长度
fmt.Println(len(str1))
//获取字符串所有字符的ASCII编码
fmt.Println([]rune(str1))
//获取字符串字符个数(长度)
fmt.Println(utf8.RuneCountInString(str1))

运行之后,输出控制台类型如下:

字符串

需要注意的是,在Go语言中,不能直接修改字符串,也就是不能通过str[1]的方式进行替换修改。如果你要修改,需要将字符串复制到一个可写的变量中,一般是[]byte或[]rune,然后在进行修改。

使用[]byte修改

对于修改字符串的单个字符,可以直接通过[]byte进行修改。示例如下:

str :="liyuanjing"
//复制
copyStr :=[]byte(str)
//修改字符
copyStr[2]='Y'
fmt.Printf("%s\n",str)
fmt.Printf("%s\n",copyStr)

需要注意的是,单个字符用’ '单引号。运行之后,输出如下:

字符串1

使用[]rune修改

话不多说,这里直接上代码。

str :="liyuanjing"
//复制
copyStr :=[]rune(str)
//修改字符
copyStr[2]='Y'
fmt.Println(str)
fmt.Println(string(copyStr))

运行之后的效果,如前文所示。

指针类型

学过C语言的应该很容易理解指针,它就是变量存储的一个内存地址的变量类型。比如,大家可以把内存想象成一个顺序存储的方格(只是比喻)。

假如定义的a变量存储6这个数,那么a肯定也在方格中,那么我们可以这样定义指针指向a的内存地址。

var a int=6
var b *int=&a

指针的简单用法

下面,我们来使用指针类型。在Go语言中,可以使用“%p”,输出变量取地址后的指针值。

示例如下:

var a int=6
var b *int=&a
fmt.Printf("%p\n",&a)
fmt.Printf("%p",b)

运行之后,我们会发现这2个值是相等的,这是因为b存储的本身就是指针值(地址),而通过&a取的也是a的地址,并不是值。如果你再输入&b,意味着是指针的指针,也就是b的地址。(有点绕)

修改指针值

在每次学习心的编程语言时,读者肯定都接触过用一个临时变量,交换2个变量的值。而修改指针同样也需要这么操作。

func main() {
	a, b := 5, 8
	exchange(&a, &b)
	fmt.Println(a, b)
}

func exchange(c, d *int) {
	t := *c
	*c = *d
	*d = t
}

其实这跟Java与C中的方法,是参数还是参数的引用是一样的。如果不是指针,只是值,这么做并不能改变原始参数的值。

复合类型

数组类型

数组在任何编程语言中,都是高频使用的类型,所以学习时也要重点掌握。首先,就是掌握如何声明数组与实例化数组,示例如下:

var name[SZIE] type
//创建数组,但不初始化
var num[10] int
//创建数组,并初始化
var num = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

数组可以直接通过num[i]去修改访问值,这里不再赘述。

结构体介绍

学过C语言的,对结构体应该并不陌生。其实Go语言的结构体与C基本差不多,下面,我们来看看如何定义以及使用:

//语法
type 类型名 struct{
	字段1 类型1
	字段2 类型2
	//.....
}
//定义
type User struct {
	name string
	age int
} 

接着,我们再来看看定义并赋值后,如何使用结构体。

示例如下:

type User struct {
	name string
	age int
}

func main() {
	var lyj User=User{name:"liyuanjing",age:29}
	var fxy User=User{name:"fengxinyao",age:31}
	fmt.Println(lyj)
	fmt.Println(fxy)
	fmt.Println(lyj.age)
	fmt.Println(fxy.name)
}

运行之后,效果如下:

控制台
可以发现,我们可以直接把结构体当作一个类型来使用。也就是说,在Go语言中,我们可以自己通过结构体定义数据类型。

而使用结构体,可以直接输出,也可以通过[变量.属性]的方式,获取结构体中的单个值。同样的,结构体也可以时指针变量,这一点与C语言一样。

切片类型

切片(slice)是对数组的一个连续“片段”的引用,所以切片也可以看作一个引用类型,或者相当于Python中的list。

切片的内部结构包含内存地址、大小以及内容,一般用于快速地操作一块数据集合。如下图所示:

切片图示
其中,切片的指针指向数组,长度代表当前切片的长度,容量是当前切片的容量。容量总是大于或等于切片的长度,而且切片默认指向一段连续的内存区域。

从指定范围生成切片

切片与数组密不可分,如果将数组理解为一栋火车厢,那么切片就是把不同连续车厢出租给使用者。在出租的过程中,需要选择开始车厢与结束车厢,这个过程就会生成切片。示例如下:

var sliceBuilder [10]int
for i :=0;i<10;i++{
	sliceBuilder[i]=i+1
}
fmt.Println(sliceBuilder[5:7])
fmt.Println(sliceBuilder[8:])
fmt.Println(sliceBuilder[:5])

运行之后,控制台输出如下:
切片1
看过前面字符串获取子字符串的用户,肯定会问,切片有何区别?

怎么说呢?切片有点像C语言的指针。指针可以做运算,但代价是内存操作越界。切片在指针的基础上增加了大小,约束了切片对应的内存区域。

在切片的使用过程中,无法对切片内部的地址和大小进行手动调整,因此切片比指针更安全强大。

重置切片

如果把切片开始与结束位置都设置为0,则生成的切片将变空,代码如下:

var sliceBuilder [10]int
for i :=0;i<10;i++{
	sliceBuilder[i]=i+1
}
fmt.Println(sliceBuilder[0:0])

记住是清空,不是全部赋值为0,也就是说充值的切片没有任何元素。运行之后,效果如下:

切片2

直接声明切片

切片也是可以直接被声明的,并不一定需要从数组操作。其语法如下:

var name []Type

注意,这个看上去与数组声明的方式差不多,但有本质区别,不信的读者回头看看上面的数组。数组定义必须给定你需要创建一个多少元素的数组,而切片不需要。

示例:

var sliceInt []int
var sliceString []string
var emptySlice =[]int{}
fmt.Println(sliceInt,sliceString,emptySlice)
fmt.Println(len(sliceInt),len(sliceString),len(emptySlice))
fmt.Println(sliceString==nil)
fmt.Println(sliceInt==nil)
fmt.Println(emptySlice==nil)

运行之后,效果如下:

切片3

需要注意的是,切片是动态结构,只能与nil判定相等,不能互相判定相等。在声明了切片之后,可以使用append()方法向切片中添加元素。如果需要创建一个指定长度的切片,则可以使用make()方法创建。

sliceInt :=make([]int,6,10)
fmt.Println(sliceInt)

上面声明了一个长度为6,容量为10的切片,控制台会输出6个0的切片。

用make()函数生成的切片会发生内存分配操作。但如果给定了开始与结束位置(包括切片复位)的切片,则只是将新的切片结构指向已经分配的内存区域。设置开始与结束位置,不会发生内存分配操作。

Map

Map就是“键值对”的无序集合。元素包含一个key,与一个Value。有时候也会成为字典。其定义的语法如下:

var student map[string]string
var user = map[string]string{"liyuanjing": "29", "fengxiangyao": "29"}
student =make(map[string]string)//删除这行在测试
student["liyuanjing"] = "29"
fmt.Println(student)
fmt.Println(user)

运行之后,控制台输出如下:

Map
如上面注释一样,如果删除make函数那一样,肯定会报错。这是因为在声明student 后并未初始化它,所以它的值是nil,不指向任何内存地址。需要通过make方法分配确定的内存地址,程序修改后即可正常运行。

在我们的项目中,有时候Key并不仅仅只对应一个Value,如果要key对应多个值,那么Map应该怎么做?示例如下:

map1 := make(map[int][]int)
map1[22]=[]int{1,2,3,4,5}
fmt.Println(map1)

运行之后,效果如下:

Map2

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go Web编程实战(3)----数据类型 的相关文章

随机推荐

  • Flex布局详解

    目录 一 Flex 布局是什么 二 基本概念 三 容器的属性 3 1 flex direction属性 3 2 flex wrap属性 3 3 flex flow 3 4 justify content属性 3 5 align items属
  • 将Hypert-V转化为VM虚拟机

    一 准备工具 V2V Converter P2V Converter Converting VM Formats 二 操作步骤 第一步 选中要转化的镜像 第二步 选择目标的镜像格式 第三步 选择生成目录 完成后点击Finish 第五步 打开
  • 常用的相似度计算方法原理及实现

    在数据分析和数据挖掘以及搜索引擎中 我们经常需要知道个体间差异的大小 进而评价个体的相似性和类别 常见的比如数据分析中比如相关分析 数据挖掘中的分类聚类 K Means等 算法 搜索引擎进行物品推荐时 相似度就是比较两个事物的相似性 一般通
  • SeleniumLibrary4.5.0 关键字详解(四)

    SeleniumLibrary4 5 0 关键字详解 四 库版本 4 5 0 库范围 全局 命名参数 受支持 简介 SeleniumLibrary是Robot Framework的Web测试库 本文档说明了如何使用SeleniumLibra
  • C++数据结构类的自实现,封装栈,循环队列

    my Queue h ifndef MY QUEUE H define MY QUEUE H class My Queue private int m queue 队列空间指针 int front 队头 int tail 队尾 int m
  • SQL Server(四) - 插入、更新和删除数据

    1 主要内容 通过SSMS 插入 更新和删除表数据 通过INSERT语句向表中插入数据 通过UPDATE语句更新表内数据 通过DELETE语句删除表内数据 使用INSERT UPDATE和DELETE语句的几个技巧2 使用INSERT语句插
  • Java lang3的 StringUtils.isNumeric(str)不能识别负数和小数

    Java lang3的 StringUtils isNumeric str 不能识别负数和小数 StringUtils isNumeric null false StringUtils isNumeric false StringUtils
  • 带你入门使用SSM+Thymeleaf先感受下基本运行和什么是SpringMVC吧

    通俗点讲SSM框架指的是Spring Boot Spring MVC Mybatis Thymeleaf是一个页面模板 这篇文章旨在 教会创建一个SSM项目 和配合Thymeleaf进行项目开发 此文章图多 所以长度很长 但干货满满 如果想
  • 前置路由守卫

    路由守卫 他是一个方法 拦截路由 路由守卫写在路由暴露之前 在这个方法中会传递一个回调函数 回调函数中传递3个参数 router beforeEach gt 也叫做前置路由守卫 里面有3个参数 to 到哪里去 from 从哪里来 next
  • JAVA基础之增删改查

    开发工具 eclipse 数据库 Oracle 项目分析 数据库的搭建 项目结构 一 主界面 采用无刷新的方法 该方法需要用到jQuery插件 界面展示 分页 删除 模糊查询 教员 班级 爱好 代码展示
  • 递推典型算法:猴子爬山,跳台阶,爬楼梯(牛客网)、魔法深渊(快手)----Python、Java

    递推算法的基本思想是把一个复杂的 庞大的计算过程转化为简单过程的多次重复 其首要问题是得到相邻的数据项之间的关系 即递推关系 以猴子爬山为例 1 问题的提出 一个顽猴在一座有30级太假的小山上爬山活跃 猴子上一步可跳1级或者3级 试求上山的
  • win10黑屏假死怎么解决

    现在很多用户都是使用的win10电脑 但是电脑使用久了之后出现一些问题时在所难免的 例如最近就有网友反映说自己的win10纯净版电脑出现了开机后黑屏假死的情况 该如何处理呢 赶紧看看吧 解决教程如下 1 win10系统开机的时候一直按F8直
  • 【Python】python使用docxtpl生成word模板

    python使用docxtpl生成word模板 python docxtpl包简单使用和实战 Python处理word docx文件 最近需要处理一些爬虫得到的数据来进行一些自动化报告的操作 因为需要生成的是word的报告 所以估选用doc
  • Mastering_Rust(译):内存,生命周期和借用(完+1)

    Rust让你 开发人员自己处理内存 但是 它可以帮助您完成内存分配的抽象和语言支持 它的生命周期 所有权和借用系统可能是您熟悉的C 世界的概念 Rust拥有所有这些 不仅仅是概念 而是语言以及编译时检查 使这一类最困难的运行时问题变得更容易
  • 神经网络调优 --- batch_size

    batchsize和收敛速度 性能的关系 一般来说 在合理的范围之内 越大的 batch size 使下降方向越准确 震荡越小 小的 bath size 引入的随机性更大 单次epoch耗时更久 且震荡大难以收敛 但大的batchsize容
  • SQL注入漏洞简介、原理及防护

    目录 1 SQL注入漏洞简介 2 SQL注入漏洞原理 3 SQL注入的分类 4 注入方法 5 SQL注入危害 6 SQL注入防护措施 1 SQL注入漏洞简介 SQL注入漏洞是Web层面最高位的漏洞之一 所谓SQL注入 就是通过把SQL命令插
  • Ubunto18.04安装完成后没有gcc、make、g++、无法访问域名等解决方法

    Ubunto18 04安装完成后没有gcc make g 无法访问域名等解决方法 今天新安装完虚拟机后又安装了Ubunto 然后就碰到了个恶心的事情 就是这是个纯净版 里面好多东西都没有 没有gcc make等等 按照其他博主的方法都不好使
  • 本地电脑与阿里云服务器之间实现文件传输

    文章目录 1 文件传输 1 1 服务器使用本地文件 1 2 使用FileZilla软件 1 2 1 服务端配置 1 2 2 客户端配置 1 2 3 问题及解决 1 2 3 1 bug 1 2 3 2 原因 1 2 3 3 解决 1 2 3
  • 解决“ warning C276: constant in condition expression“和“warning C294: unreachable code“两个告警提示

    好久不见 最近因为一些项目比较忙 都没怎么发文章了 今天有空就来分享一下自己之前遇到的两个告警 告警信息 首先 我们先来看一下这两个告警 第一个告警为 warning C276 constant in condition expressio
  • Go Web编程实战(3)----数据类型

    目录 前言 布尔型 数字类型 字符串类型 使用 byte修改 使用 rune修改 指针类型 指针的简单用法 修改指针值 复合类型 数组类型 结构体介绍 切片类型 从指定范围生成切片 重置切片 直接声明切片 Map 前言 Go语言数据类型包括