【Go语言】语法基础之变量、数据类型详解

🐇明明跟你说过:个人主页

🏅个人专栏:《Go语言探索之旅》🏅

🔖行路有良友,便是天堂🔖

目录

一、引言

1、Go语言简介

2、Go语言特点

二、变量

1、变量的声明与初始化

2、变量的作用域 

三、数据类型

1、基本数据类型

1. 整数类型(int,uint,byte等)

2. 浮点类型

3. 布尔类型

4. 字符串类型

5. 复数类型

2、复合数据类型

1. 数组(Array)

2. 切片(Slice)

3. 映射(Map)

4. 结构体(Struct)

3、类型转换

1. 整数类型转换

2. 浮点数类型转换

3. 字符串到整数类型转换

4. 整数到字符串类型转换

5. 切片到数组类型转换

6. 数组到切片类型转换

7. 映射(Map)相关的类型转换

8. 结构体类型转换

9. 类型断言


一、引言

1、Go语言简介

Go语言,又称Golang,是由Google公司开发的一种现代编程语言。它起源于2007年,并在2009年正式对外发布。Go语言旨在提高软件开发的效率、可靠性和可维护性,特别在处理并发性方面表现出色。

2、Go语言特点

  1. 并发性支持:Go语言内置并发性支持,允许开发者构建高度并发和可扩展的应用。它提供了goroutine(轻量级线程)和channel(通信管道)等功能,简化了并发编程。
  2. 垃圾回收:Go语言拥有高效的垃圾回收机制,自动释放不再使用的内存。这减轻了开发者管理内存的负担,提高了程序的稳定性和可靠性。
  3. 类型安全:Go语言是一种强类型语言,提供了严格的类型检查机制。这有助于捕获类型错误,确保代码的可靠性。
  4. 跨平台性:Go语言编译成可执行文件后,可以在不同的操作系统(如Linux、Windows、macOS)上运行,无需进行重新编译。
  5. 高性能:Go语言编译器生成高度优化的机器代码,使程序运行速度快且资源消耗低。它特别适合处理高并发和数据密集型应用。

二、变量

1、变量的声明与初始化

1. 使用 var 关键字声明变量
使用 var 关键字声明变量是最基本的形式。可以声明一个或多个变量,并分别初始化它们:

var (x int         // 声明一个 int 类型的变量 xy string      // 声明一个 string 类型的变量 yz float64     // 声明一个 float64 类型的变量 z
)// 初始化变量
x = 10
y = "hello"
z = 3.14


2. 使用 := 简化声明和初始化
如果想要在声明的同时初始化变量,可以使用 := 运算符,这种方式被称为“简短变量声明”。这种方式只在函数内部有效:

a := 10        // 声明并初始化一个 int 类型的变量 a
b := "world"   // 声明并初始化一个 string 类型的变量 b
c := 2.718     // 声明并初始化一个 float64 类型的变量 c


3. 同时声明多个变量
可以在一行中声明并初始化多个变量:

var (d int    = 100 // 声明并初始化一个 int 类型的变量 de string = "Go" // 声明并初始化一个 string 类型的变量 ef float64 = 1.618 // 声明并初始化一个 float64 类型的变量 f
)


或者使用简短声明:

g, h, i := 1000, "Programming", 3.14159


4. 使用 new 函数
new 函数可以用来为变量分配内存,并返回指向该内存的指针:

j := new(int) // 分配 int 类型的内存,并返回指向该内存的指针
*k := 1000    // 给指针 k 所指向的 int 类型内存赋值


5. 使用 make 函数
对于某些类型(如切片、映射和通道),需要使用 make 函数来初始化:

slice := make([]int, 5) // 创建一个长度为 5 的 int 类型切片
mapVar := make(map[string]int) // 创建一个 string 到 int 的映射
channel := make(chan int) // 创建一个 int 类型的通道


6. 匿名变量
在某些情况下,可能会使用匿名变量(通常写作 _),主要用于忽略不需要的返回值:

_, err := os.Open("file.txt") // 忽略第一个返回值
if err != nil {log.Fatal(err)
}


7. 初始化复合类型
可以一次性初始化数组、切片、映射等复合类型:

// 数组
arr := [3]int{1, 2, 3}// 切片
slice := []int{1, 2, 3}// 映射
mapVar := map[string]int{"one": 1, "two": 2, "three": 3}

2、变量的作用域 

在 Go 语言中,变量的作用域决定了变量的可见性和生命周期。作用域的定义有助于避免命名冲突,并确保变量在适当的时候被创建和销毁。Go 语言中的变量作用域主要有以下几种:

1. 包级变量(Package-Level Variables)
包级变量在整个包内可见,并且在整个程序运行期间存在。这类变量通常用于在包内共享状态。

package mainvar globalVar int // 包级变量func main() {globalVar = 10fmt.Println(globalVar)
}


2. 函数级变量(Function-Level Variables)
函数级变量在一个函数的范围内可见,并且在函数被调用时创建,在函数返回时销毁。

package mainimport "fmt"func main() {funcLevelVar := 10 // 函数级变量fmt.Println(funcLevelVar)
}


3. 块级变量(Block-Level Variables)
块级变量在一个代码块(由 {} 围绕的部分)内可见,并且在进入该代码块时创建,在离开该代码块时销毁。

package mainimport "fmt"func main() {if true {blockLevelVar := 10 // 块级变量fmt.Println(blockLevelVar)}// blockLevelVar 不可见
}


4. 形参(Function Parameters)
函数的形参在函数调用时创建,并在函数返回时销毁。形参的作用域限于函数体内。

package mainimport "fmt"func printSum(a, b int) { // 形参 a 和 bsum := a + bfmt.Println(sum)
}func main() {printSum(3, 4)
}


5. 循环变量
在循环中声明的变量在循环体内可见,并且在每次迭代时创建,在迭代结束后销毁。

package mainimport "fmt"func main() {for i := 0; i < 5; i++ { // 循环变量 ifmt.Println(i)}// i 在循环外部不可见
}


6. 闭包中的外部变量
在闭包中,闭包可以访问定义在其外围作用域中的变量。这些变量的作用域扩展到了闭包的生命周期内。

package mainimport "fmt"func main() {x := 10 // 外围作用域中的变量f := func() {fmt.Println(x)}f() // 输出 x 的值
}


7. 匿名变量
匿名变量(通常写作 _)用于忽略不需要的返回值或变量。

package mainimport ("fmt""os"
)func main() {_, err := os.Open("file.txt")if err != nil {fmt.Println("Error opening file:", err)}
}

三、数据类型

1、基本数据类型

1. 整数类型(int,uint,byte等)

整数类型用于表示整数值,包括有符号整数和无符号整数。

有符号整数类型

  • int:默认的整数类型,其大小取决于操作系统(32位或64位)。
  • int8:8位有符号整数,范围为 -128 到 127。
  • int16:16位有符号整数,范围为 -32768 到 32767。
  • int32:32位有符号整数,范围为 -2^31 到 2^31-1。
  • int64:64位有符号整数,范围为 -2^63 到 2^63-1。

无符号整数类型

  • uint:默认的无符号整数类型,其大小取决于操作系统(32位或64位)。
  • uint8:8位无符号整数,范围为 0 到 255。
  • byte:别名类型,等同于 uint8。
  • uint16:16位无符号整数,范围为 0 到 65535。
  • uint32:32位无符号整数,范围为 0 到 2^32-1。
  • uint64:64位无符号整数,范围为 0 到 2^64-1。
  • uintptr:用于存储指针地址的整数类型,其大小取决于操作系统(32位或64位)。

2. 浮点类型

浮点类型用于表示带有小数部分的数字。

  • float32:32位浮点数,约7位精度。
  • float64:64位浮点数,约15位精度。

3. 布尔类型

布尔类型用于表示真或假的值。

  • bool:布尔值,可以是 true 或 false。

4. 字符串类型

字符串类型用于表示文本。

  • string:用于表示文本的字符串类型。

5. 复数类型

复数类型用于表示具有实部和虚部的数值。

  • complex64:包含实部和虚部的32位复数。
  • complex128:包含实部和虚部的64位复数。

示例代码

package mainimport ("fmt"
)func main() {// 整数类型var intVar int = 42var int8Var int8 = -128var int16Var int16 = 32767var int32Var int32 = 2147483647var int64Var int64 = 9223372036854775807var uintVar uint = 42var uint8Var uint8 = 255var uint16Var uint16 = 65535var uint32Var uint32 = 4294967295var uint64Var uint64 = 18446744073709551615var byteVar byte = 'A' // 等同于 uint8var uintptrVar uintptr = 12345// 浮点类型var float32Var float32 = 3.14var float64Var float64 = 3.1415926535// 布尔类型var boolVar bool = true// 字符串类型var stringVar string = "Hello, World!"// 复数类型var complex64Var complex64 = 3 + 4ivar complex128Var complex128 = 3 + 4i// 输出变量的值fmt.Printf("intVar = %d\n", intVar)fmt.Printf("int8Var = %d\n", int8Var)fmt.Printf("int16Var = %d\n", int16Var)fmt.Printf("int32Var = %d\n", int32Var)fmt.Printf("int64Var = %d\n", int64Var)fmt.Printf("uintVar = %d\n", uintVar)fmt.Printf("uint8Var = %d\n", uint8Var)fmt.Printf("uint16Var = %d\n", uint16Var)fmt.Printf("uint32Var = %d\n", uint32Var)fmt.Printf("uint64Var = %d\n", uint64Var)fmt.Printf("byteVar = %c\n", byteVar)fmt.Printf("uintptrVar = %d\n", uintptrVar)fmt.Printf("float32Var = %f\n", float32Var)fmt.Printf("float64Var = %f\n", float64Var)fmt.Printf("boolVar = %t\n", boolVar)fmt.Printf("stringVar = %s\n", stringVar)fmt.Printf("complex64Var = %v\n", complex64Var)fmt.Printf("complex128Var = %v\n", complex128Var)
}

2、复合数据类型

Go 语言提供了多种复合数据类型来处理更复杂的数据结构。以下是一些常见的复合数据类型及其描述:

1. 数组(Array)

数组是一种固定大小的序列类型,用于存储相同类型的元素。数组的长度在声明时确定,并且不可改变。

package mainimport "fmt"func main() {// 声明并初始化数组var numbers [5]int = [5]int{1, 2, 3, 4, 5}// 访问数组元素fmt.Println("numbers[0] =", numbers[0])fmt.Println("numbers[4] =", numbers[4])// 遍历数组for i := range numbers {fmt.Println("numbers[", i, "] =", numbers[i])}// 声明并初始化不同类型的数组var letters = [5]string{"a", "b", "c", "d", "e"}var floats = [5]float64{1.1, 2.2, 3.3, 4.4, 5.5}// 打印数组fmt.Println("letters =", letters)fmt.Println("floats =", floats)
}


2. 切片(Slice)

切片是基于数组的一种动态数据结构,它可以动态地增长和缩减。切片提供了一种灵活的方式来管理序列数据。

package mainimport "fmt"func main() {// 声明并初始化切片var numbers = []int{1, 2, 3, 4, 5}// 访问切片元素fmt.Println("numbers[0] =", numbers[0])fmt.Println("numbers[4] =", numbers[4])// 遍历切片for i, v := range numbers {fmt.Println("numbers[", i, "] =", v)}// 修改切片numbers[0] = 10fmt.Println("Modified numbers =", numbers)// 切片的追加numbers = append(numbers, 6)fmt.Println("Appended numbers =", numbers)// 切片的切分subSlice := numbers[1:4]fmt.Println("Subslice =", subSlice)
}


3. 映射(Map)

映射是一种关联类型,它通过键值对来存储数据。键必须是可比较的类型(如 int、string、struct 等),值可以是任意类型。

package mainimport "fmt"func main() {// 声明并初始化映射var ageMap = map[string]int{"Alice": 30,"Bob":   25,"Charlie": 22,}// 访问映射元素fmt.Println("ageMap[Alice] =", ageMap["Alice"])fmt.Println("ageMap[Bob] =", ageMap["Bob"])// 遍历映射for key, value := range ageMap {fmt.Println("key =", key, "value =", value)}// 修改映射ageMap["Alice"] = 31fmt.Println("Updated ageMap =", ageMap)// 添加新的键值对ageMap["David"] = 28fmt.Println("Updated ageMap =", ageMap)// 删除映射中的键值对delete(ageMap, "Charlie")fmt.Println("Updated ageMap =", ageMap)
}


4. 结构体(Struct)

结构体是一种自定义的数据类型,它允许你组合不同的数据类型来形成新的类型。

package mainimport "fmt"type Person struct {Name stringAge  intAddress Address
}type Address struct {Street stringCity   string
}func main() {// 声明并初始化结构体var person = Person{Name: "Alice",Age:  30,Address: Address{Street: "123 Main St",City:   "Anytown",},}// 访问结构体成员fmt.Println("person.Name =", person.Name)fmt.Println("person.Age =", person.Age)fmt.Println("person.Address.Street =", person.Address.Street)fmt.Println("person.Address.City =", person.Address.City)
}

3、类型转换

在 Go 语言中,类型转换是指将一个变量或表达式的类型转换为另一种类型。类型转换在某些情况下是必要的,尤其是在需要将一种类型的数据作为另一种类型来处理时。

基本类型转换

1. 整数类型转换

将整数类型从一种转换为另一种类型,例如从 int 转换为 int32。

import "fmt"func main() {var i int = 10var i32 int32 = int32(i) // 类型转换fmt.Printf("Original integer: %d, Converted integer: %d\n", i, i32)
}


2. 浮点数类型转换

将浮点数类型从一种转换为另一种类型,例如从 float32 转换为 float64。

package mainimport "fmt"func main() {var f32 float32 = 3.14var f64 float64 = float64(f32) // 类型转换fmt.Printf("Original float32: %f, Converted float64: %f\n", f32, f64)
}


3. 字符串到整数类型转换

将字符串类型转换为整数类型,例如从 string 转换为 int。

package mainimport ("fmt""strconv"
)func main() {s := "123"i, err := strconv.Atoi(s) // 字符串转整数if err == nil {fmt.Printf("Converted integer: %d\n", i)} else {fmt.Println("Conversion error:", err)}
}

4. 整数到字符串类型转换

将整数类型转换为字符串类型,例如从 int 转换为 string。

package mainimport ("fmt""strconv"
)func main() {i := 123s := strconv.Itoa(i) // 整数转字符串fmt.Printf("Converted string: %s\n", s)
}


复合类型转换

5. 切片到数组类型转换

将切片转换为数组,需要注意的是,切片和数组的长度必须相等。

package mainimport "fmt"func main() {s := []int{1, 2, 3}var a [3]intcopy(a[:], s) // 切片转数组fmt.Printf("Converted array: %v\n", a)
}


6. 数组到切片类型转换

将数组转换为切片,可以通过切片操作来实现。

package mainimport "fmt"func main() {a := [3]int{1, 2, 3}s := a[:] // 数组转切片fmt.Printf("Converted slice: %v\n", s)
}


7. 映射(Map)相关的类型转换

在映射中,键和值的类型转换通常在插入或检索时进行。

package mainimport "fmt"func main() {m := map[string]int{"one":   1,"two":   2,"three": 3,}val, ok := m["one"]if ok {strVal := strconv.Itoa(val) // 将整数转换为字符串fmt.Printf("Converted value: %s\n", strVal)}
}


8. 结构体类型转换

在某些情况下,可能需要将结构体转换为另一种类型,例如将一个结构体嵌入另一个结构体。

package mainimport "fmt"type Point struct {X intY int
}type Circle struct {PointRadius int
}func main() {p := Point{X: 10, Y: 20}c := Circle{Point: p, Radius: 5} // 结构体嵌入fmt.Printf("Circle: %+v\n", c)
}


9. 类型断言

类型断言用于从接口(interface)中提取具体的类型值。

package mainimport ("fmt"
)func main() {var i interface{} = "hello"if str, ok := i.(string); ok {fmt.Println("String value:", str)}
}

  💕💕💕每一次的分享都是一次成长的旅程,感谢您的陪伴和关注。希望这些关于Go语言的文章能陪伴您走过技术的一段旅程,共同见证成长和进步!😺😺😺

🧨🧨🧨让我们一起在技术的海洋中探索前行,共同书写美好的未来!!! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/57709.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++篇】C++类与对象深度解析(五):友元机制、内部类与匿名对象的讲解

文章目录 前言 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助&#xff01…

时序数据库 TDengine 支持集成开源的物联网平台 ThingsBoard

Thingsboard 中“设备配置”和“设备”的关系是一对多的关系&#xff0c;通过设备配置为每个设备设置不同的配置&#xff0c;每个设备都会有一个与其关联的设备配置文件。等等&#xff0c;这不就是TDengine 中超级表的概念&#xff1a; 超级表是一种特殊的表结构&#xff0c;用…

【功能安全】汽车功能安全个人认证证书

目录 1、证书 2、课程信息 &#x1f4d6; 推荐阅读 1、证书 汽车功能安全工程师去拿类似莱茵、SGS、南德颁发的证书&#xff0c;如下&#xff1a; 2、课程信息 一般上什么课程了&#xff0c;课程信息大概如下&#xff1a; 汽车功能安全工程师认证课 &#xff08;3天&#…

数据库作业2

建立并使用mydb8_worker&#xff0c;并在其中建表&#xff1a; &#xff08;1&#xff09;显示所有职工的基本信息 &#xff08;2&#xff09;去重查询 &#xff08;3&#xff09;所有职工人数 &#xff08;4&#xff09;最高最低工资 &#xff08;5&#xff09;平均工资和总工…

2024“龙信杯“电子数据取证竞赛-手机取证题目Writeup

文章关键词&#xff1a;电子数据取证、电子物证、手机取证、服务器取证、介质取证 案情介绍 近期&#xff0c;某公安机关正式受理了一起受害者报案案件。受害者陈述称&#xff0c;其通过微信平台结识了一名自称为相亲中介服务的客服人员。该客服人员诱骗受害者参与所谓的“相亲…

【AscendC算子开发】笔记1 算子开发哲学

重看这门课&#xff0c;有很多内容的认识更深了&#xff0c;做一些记录。 为什么不能将网络节点融合 这个问题关联到另一个问题&#xff1a;为什么我们需要激活函数&#xff1f; 使用线性的神经元堆叠得到的方程最后也是线性方程&#xff0c;无法表征非线性的信息&#xff0c…

一文1800字从0到1浅谈web性能测试!

什么是性能测试&#xff1f; web性能应该注意些什么&#xff1f; 性能测试&#xff0c;简而言之就是模仿用户对一个系统进行大批量的操作&#xff0c;得出系统各项性能指标和性能瓶颈&#xff0c;并从中发现存在的问题&#xff0c;通过多方协助调优的过程。而web端的性能测试…

基于知识图的电影推荐系统

&#x1f3ac; 毕设灵感——“基于知识图谱的电影推荐系统”&#x1f680; &#x1f449; 如果你的毕业设计还没有灵感&#xff0c;那么这个基于知识图谱的电影推荐系统绝对值得参考&#xff01;这不是普通的推荐系统&#xff0c;而是通过知识图谱大数据的结合&#xff0c;来为…

Genmo 的 Mochi1 AI 视频生成技术:内容创作的新纪元

Genmo 的 Mochi1 AI 视频生成技术&#xff1a;内容创作的新纪元 随着 AI 技术的快速发展&#xff0c;AI 视频生成工具已经成为许多创作者的重要工具。Genmo 最新推出的 Mochi1 技术&#xff0c;作为一款开源的 AI 视频生成工具&#xff0c;为内容创作者提供了极具创新性的视频…

详解:CentOS 7 NAT模式的网络配置

打开虚拟机发现并没有网络选项 一、解决虚拟机ping通主机 解决方法1&#xff1a; 启动VMware NAT Service &#xff08;1&#xff09;首先查看主机的ip地址&#xff0c;winR打开搜索框&#xff0c;输入cmd &#xff08;2&#xff09;输入ipconfig查看网络配置信息 ipcon…

Bug:通过反射修改@Autowired注入Bean的字段,明确存在,报错 NoSuchFieldException

【BUG】通过Autowired注入了一个Bean SeqNo&#xff0c;测试的时候需要修改其中的字段。通过传统的反射&#xff0c;无论如何都拿不到信息&#xff0c;关键是一方面可以通过IDEA跳转&#xff0c;一方面debug也确实能看到这个字段。但是每次调用set方法报错&#xff1a;NoSuchFi…

腾讯云轻量服务器Lighthouse的前世今生

目录 序一、名字的由来二、Lighthouse的定位是什么&#xff0c;与CVM的差异化有哪些三、Lighthouse是如何实现简单易用的四、Lighthouse对于开发者有哪些具体的利好 序 印象中&#xff0c;腾讯云轻量应用服务器Lighthouse是在2020年正式上线的。 在其一经推出后&#xff0c;就…

【C++进阶】之C++11的简单介绍(三)

&#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f49a;代码仓库&#xff0c;欢迎访问 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f30f; 任尔江湖满血骨&#xff0c;我自踏雪寻梅香。 万千浮云遮碧…

Vue项目实战-新能源汽车可视化(一)(持续更新中)

一.项目代码 1.App.vue <template><!-- 模板--><div id"wrapper"><div style"width: 100%"><el-tabs v-model"activeName" id"tabs"> <!-- 标签栏里包含了三个标签面板&#xff0c;分别是研发与维…

web前端-html:简单创建表格表单相结合的网页

效果&#xff1a; <body><form action"这里如果为空表单提交后不会有任何操作"method"get"<label for"edit">用户名</label><input type"text" name"用户名" id"最好不要空&#xff0c;id属性…

【论文学习与撰写】论文里配图的题注、多张图片同列排版格式等

目录 1、插入题注 2、多张图排版 1、插入题注 word--引用--插入题注&#xff0c;就会出来这个 直接点确定的话&#xff0c;是会出来图1/图2/图3.。。。之类的 那是因为标签设置的是 图 如图新建标签为&#xff1a; 图 1. 那么&#xff0c;插入题注之后&#xff0c;就会…

【分立元件】贴片电阻的额定功率

贴片电阻器通过电流后将会发热。而贴片电阻的额定功率(Power Rating)是在额定环境温度中可在连续工作状态下使用的最大功率值。 此外,由于使用温度的上限是确定的,因此在高于额定环境温度的条件下使用时,需要按照以下的功率降额曲线来降低功率。额定环境温度是能够…

ionic Capacitor 生成 Android 应用

官方文档 https://ionic.nodejs.cn/developing/android/ https://capacitorjs.com/docs/getting-started 1、创建新的 Capacitor 应用程序 空目录下面 npm init capacitor/app2、install Capacitor npm install npm start在这里插入图片描述 3、生成dist目录 npm run buil…

SpringBoot篇(缓存层)

目录 前言 缓存是什么&#xff1f; 一、SpringBoot内置缓存解决方案 1. 简介 2. 手机验证码案例 二、SpringBoot整合Ehcache缓存 1. 简介 2. 总结 三、SpringBoot整合Redis缓存 1. 简介 2. 总结 四、SpringBoot整合Memcached缓存 1. 简介 2. 安装 3. 变更缓存为M…

5G 现网信令参数学习(1) - MIB

MIB消息中的参数 systemFrameNumber 000101B, subCarrierSpacingCommon scs30or120, ssb-SubcarrierOffset 6, dmrs-TypeA-Position pos2, pdcch-ConfigSIB1 { controlResourceSetZero 10, searchSpaceZero 4 }, cellBarred notBarred, intraFreqReselection allowed, sp…