极速Go语言入门(超全超详细)-基础篇

news2024/11/16 9:44:25

文章目录

  • GoLang概述
    • Go语言三大牛
    • 谷歌创造Golang的原因
    • Golang 的发展历程
    • Golang 的语言的特点
  • Go语言开发工具
  • Go开发环境配置(sdk下载及配置)
  • 使用开发工具创建第一个Go项目
  • Go 程序开发的注意事项
  • 官方参考文档
  • Go学习
    • Go变量
    • 数据类型
    • 标识符
    • 运算符
    • 键盘输入语句
    • 程序流程控制

Golang概述

Go语言三大牛

在这里插入图片描述

谷歌创造Golang的原因

在这里插入图片描述

Golang 的发展历程

 2007 年,谷歌工程师 Rob Pike, Ken Thompson 和 Robert Griesemer 开始设计一门全新的语言,这是
Go 语言的最初原型。
**2009 年 11 月 10 日,Google 将 Go 语言以开放源代码的方式向全球发布。 **
**2015 年 8 月 19 日,Go 1.5 版发布,本次更新中移除了”最后残余的 C 代码” **
**2017 年 2 月 17 日,Go 语言 Go 1.8 版发布。 **
**2017 年 8 月 24 日,Go 语言 Go 1.9 版发布。 1.9.2 版本 **
2018 年 2 月 16 日,Go 语言 Go 1.10 版发布。

Golang 的语言的特点

Go 语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发维护的高效率 ,使用一个表达式来形容 Go 语言:Go = C + Python , 说明 Go 语言既有 C 静态语言程序的运行速度,又能达到 Python 动态语言的快速开发。

  1. 从 C 语言中继承了很多理念,包括表达式语法,控制结构,基础数据类型,调用参数传值,指针

等,也保留了和 C 语言一样的编译执行方式及弱化的指针

举一个案例(体验):
//go 语言的指针的使用特点(体验)
func testPtr(num *int) {
*num = 20
}

  1. 引入包的概念,用于组织程序结构,Go 语言的一个文件都要归属于一个包,而不能单独存在。
package main //一个文件都要归属于一个包

import "fmt"

func main() {
	fmt.Println("hello word")
}
  1. 垃圾回收机制,内存自动回收,不需开发人员管理
  2. 天然并发 (重要特点)
    1. 从语言层面支持并发,实现简单
    2. goroutine,轻量级线程,可实现大并发处理,高效利用多核。
    3. 基于 CPS 并发模型(Communicating Sequential Processes )实现
  3. 吸收了管道通信机制,形成 Go 语言特有的管道 channel 通过管道 channel , 可以实现不同的 goroute

之间的相互通信。

  1. 函数可以返回多个值。举例:

**//写一个函数,实现同时返回 和,差 **
**//go 函数支持返回多个值 **
**func getSumAndSub(n1 int, n2 int) (int, int ) { **
**sum := n1 + n2 //go 语句后面不要带分号. **
**sub := n1 - n2 **
**return sum , sub **
**} **

  1. 新的创新:比如切片 slice、延时执行 defer

Go语言开发工具

我使用的是GoLand开发工具,比较顺手
GoLand 是 JetBrains 公司推出的 Go 语言集成开发环境。GoLand 同样基于 IntelliJ 平台开发,支持 JetBrains 的插件体系。

下载地址:https://www.jetbrains.com/go/download/other.html
自己选择喜欢的版本和相应的系统下载,不建议使用太新的版本,我自己用2021.3.5版本比较顺手

账号的话可以去淘宝买教育注册渠道,注册后可以使用一年
或者使用插件无限使用30天(⚠️注意21年及之前的可以使用,相对新的版本不支持),相关文档地址:https://blog.csdn.net/qq_37699336/article/details/116528062

Go开发环境配置(sdk下载及配置)

SDK 下载地址:Golang 中国 https://www.golangtc.com/download
sdk配置相关参考文档:https://blog.csdn.net/m0_49589654/article/details/127259754

使用开发工具创建第一个Go项目

创建一个项目,选择好sdk的路径就可以了

在这里插入图片描述

右击项目文件创建一个go file

在这里插入图片描述
在这里插入图片描述
之后写个hello word

package main //一个文件都要归属于一个包

import "fmt"

func main() {
	fmt.Println("hello word")
}

运行

在这里插入图片描述

Go 程序开发的注意事项

  1. Go 源文件以 “go” 为扩展名。
  2. Go 应用程序的执行入口是 main()函数。 这个是和其它编程语言(比如 java/c)
  3. Go 语言严格区分大小写。
  4. Go 方法由一条条语句构成,每个语句后不需要分号(Go 语言会在每行后自动加分号),这也体现出 Golang 的简洁性。
  5. Go 编译器是一行行进行编译的,因此我们一行就写一条语句,不能把多条语句写在同一个,否

则报错

  1. go 语言定义的变量或者 import 的包如果没有使用到,代码不能编译通过。
  2. 大括号都是成对出现的,缺一不可。

官方参考文档

Golang 官方网站(可能访问不了): https://golang.org
Golang 中文网 在线标准库文档: https://studygolang.com/pkgdoc

Go学习

Go变量

概念:变量相当于内存中一个数据存储空间的表示,你可以把变量看做是一个房间的门牌号,通过门牌号我们可以找到房间,同样的道理,通过变量名可以访问到变量 (值)。

变量的使用步骤:声明变量(也叫:定义变量) -> 非变量赋值 -> 使用变量

package main

import "fmt"

func main() {
	//创建变量
	var a int
	//变量赋值
	a = 10
	//使用变量(进行打印)
	fmt.Println("a = ", a)
}

运行结果

a = 10
package main

import fmt "fmt"
// /全局变量///
var age, name = 18, "小明"
///全局变量///

func main() {

    //创建变量
	//变量=变量名+值+数据类型,这一点请大家注意,变量的三要素
	//Golang 的变量如果没有赋初值,编译器会使用默认值, 比如 int 默认值 0 string 默认值为空串, 小数默认为 0
	///局部变量///

	//1、创建变量但 不赋值 使用的默认值(int 默认值为0)
	var a int
	//使用变量(进行打印)
	fmt.Println("a = ", a)

	//2、创建变量但不赋予类型,根据值自行判定变量类型(类型推导)
	var b = 10
	//fmt.Printf格式化输出 %v:输出值, %T:输出值的类型 \n:换行
	fmt.Printf("b = %v, type: %T  \n", b, b)

	//3、使用:=声明变量
	//c := "Go" 等价于 var c string = "Go";
	c := "Go"
	fmt.Printf("c = %v, type: %T \n", c, c)

	//4、多变量声明,带值声明或者不带值声明
	var d, e, f int              //不带值
	var d1, e1, f1 int = 1, 2, 3 //带值(相同类型)
	d2, e2, f2 := 1, "123", 's'  //带值(相同类型)
	fmt.Println(d, e, f, "------", d1, e1, f1, "------", d2, e2, f2)

	//注意⚠️:在同一代码块中,不能对类型再次赋予类型
	//var testA int = 10;
	//testA  := 20; // ❌

	///局部变量///

	//输出全局变量
	fmt.Println(age, name)

}

运行结果

a =  0
b = 10, type: int  
c = %!d(string=Go), type: string 
0 0 0 ------ 1 2 3 ------ 1 123 115
18 小明

数据类型

在这里插入图片描述

基本数据类型说明

类型描述
uint32位或64位
uint8无符号 8 位整型 (0 到 255)
uint16无符号 16 位整型 (0 到 65535)
uint32无符号 32 位整型 (0 到 4294967295)
uint64无符号 64 位整型 (0 到 18446744073709551615)
int32位或64位
int8有符号 8 位整型 (-128 到 127)
int16有符号 16 位整型 (-32768 到 32767)
int32有符号 32 位整型 (-2147483648 到 2147483647)
int64有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)
byteuint8的别名(type byte = uint8)
runeint32的别名(type rune = int32),表示一个unicode码
uintptr无符号整型,用于存放一个指针是一种无符号的整数类型,没有指定具体的bit大小但是足以容纳指针。
uintptr类型只有在底层编程是才需要,特别是Go语言和C语言函数库或操作系统接口相交互的地方。
float32IEEE-754 32位浮点型数
float64IEEE-754 64位浮点型数
complex6432 位实数和虚数
complex12864 位实数和虚数

整型数据
分为两类,有符号和无符号两种类型

有符号: int, int8, int16, int32, int64
无符号: uint, uint8, uint16, uint32, uint64, byte
不同位数的整型区别在于能保存整型数字范围的大小;
有符号类型可以存储任何整数,无符号类型只能存储自然数
int和uint的大小和系统有关,32位系统表示int32和uint32,如果是64位系统则表示int64和uint64
byte与uint8类似,一般用来存储单个字符
在保证程序正确运行下,尽量使用占用空间小的数据类型
fmt.Printf(“%T”, var_name)输出变量类型
unsafe.Sizeof(var_name)查看变量占用字节

浮点型

浮点型也就是小数类型,可以存放小数。比如6.6,-12.34
1、关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位
2、尾数部分可能丢失,造成精度损失。-123.0000901
3、浮点型的存储分为三部分:符号位+指数位+尾数位,在存储过程中,精度会有丢失
4、golang的浮点型默认为float64类型
5、通常情况下,应该使用float64,因为它比float32更精确
6、0.123可以简写成.123,也支持科学计数法表示:5.1234e2 等价于512.34

字符

Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存。
字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的,也就是说对于传统的字符串是由字符组成的,而Go的字符串不同,它是由字节组成的

  • 字符只能被单引号包裹,不能用双引号,双引号包裹的是字符串
  • 当我们直接输出type值时,就是输出了对应字符的ASCII码值
  • 当我们希望输出对应字符,需要使用格式化输出
  • Go语言的字符使用UTF-8编码,英文字母占一个字符,汉字占三个字符
  • 在Go中,字符的本质是一个整数,直接输出时,是该字符对应的UTF-8编码的码值。
  • 可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的unicode字符
  • 字符类型是可以运算的,相当于一个整数,因为它们都有对应的unicode码
字符类型本质探讨
  • 字符型存储到计算机中,需要将字符对应的码值(整数)找出来存储:字符 --> 码值 --> 二进制 --> 存储读取: 二进制 -->码值 --> 字符 --> 读取
  • 字符和码值的对应关系是通过字符编码表决定的(是规定好的)
  • Go语言的编码都统一成了UTF-8。非常的方便,很统一,再也没有编码乱码的困扰了
布尔型

布尔类型也叫做bool类型,bool类型数据只允许取值true或false
bool类型占1个字节
bool类型适用于逻辑运算,一般用于流程控制

字符串

字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本
1、字符串一旦赋值了,就不能修改了:在Go中字符串是不可变的。
2、字符串的两种标识形式

指针
  • 基本数据类型,变量存的就是值,也叫值类型
  • 获取变量的地址,用&,比如var num int,获取num的地址:&num
  • 指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值,比如:var ptr *int = &num
  • 获取指针类型所指向的值,使用:*,比如,var ptr int,使用ptr获取ptr指向的值

指针细节说明:

  • 值类型,都有对应的指针类型,形式为数据类型,比如int对应的指针就是int,float64对应的指针类型就是*float64,依此类推。
  • 值类型包括:基本数据类型数组结构体struct
值类型与引用类型

值类型和引用类型使用特点:
值类型:变量直接存储值,内存通常在中分配
引用类型:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在上分配,当没有任何变量应用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收。
Golang中值类型和引用类型的区分

  • 值类型:基本数据类型(int系列、float系列、bool、string)、数组和结构体
  • 引用类型:指针、slice切片、map、管道chan、interface等都是引用类型

相关示例代码

package main

import (
	"fmt"
	"strconv"
	"unsafe"
)

func main() {

    println("----byte类型----")
	//Golang 程序中整型变量在使用时,遵守保小不保大的原则,即:在保证程序正确运行下,尽量 使用占用空间小的数据类型。【如:年龄】
	//bit: 计算机中的最小存储单位。byte:计算机中基本存储单元。[二进制再详细说] 1byte = 8 bit
	var n0 byte = 10
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", n0, n0, unsafe.Sizeof(n0))

	println("----int类型----")
	//int 类型
	var n1 int = 20
	var n2 int8 = 21
	var n3 int16 = 22
	var n4 int32 = 23
	var n5 int64 = 24
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", n1, n1, unsafe.Sizeof(n1))
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", n2, n2, unsafe.Sizeof(n2))
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", n3, n3, unsafe.Sizeof(n3))
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", n4, n4, unsafe.Sizeof(n4))
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", n5, n5, unsafe.Sizeof(n5))

	println("----float类型----")
	//float 类型
	var f1 float32 = 30.23748734872346 //会损失精度,如果我们要保存一个精度高的数,则应该选用 float64
	var f2 float64 = 21.23748734872346
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", f1, f1, unsafe.Sizeof(f1))
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", f2, f2, unsafe.Sizeof(f2))

	println("----字符类型----")
	//字符类型(英文字母占1 个字节 汉字占3 个字节), 可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的 unicode 字符
	//Go 语 言 的 字 符 使 用 UTF-8 编 码 , 如 果 想 查 询 字 符 对 应 的 utf8 码 值 http://www.mytju.com/classcode/tools/encode_utf8.asp
	//不理解utf-8、ASCII和Unicode可以看考这篇文章:https://www.bilibili.com/read/cv16001311/
	var c0 int = 's'
	var c1 int = '北'
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d, 显示信息=%c \n", c0, c0, unsafe.Sizeof(c0), c0)
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d, 显示信息=%c \n", c1, c1, unsafe.Sizeof(c1), c1)

	println("----布尔类型----")
	//bool 类型占 1 个字节。适于逻辑运算,一般用于程序流程控制
	var flagControl bool = true
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", flagControl, flagControl, unsafe.Sizeof(flagControl))
	for i := 0; i < 100; i++ {
		if i == 10 {
			//do something
			flagControl = false
		}
		if flagControl == false {
			fmt.Println("结束循环, i= ", i)
			break
		}
	}

	println("----string 类型----")
	//字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本
	//Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本,这样 Golang 统一使用 UTF-8 编码,中文 乱码问题不会再困扰程序员。
	var str string = "测试字符串"
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", str, str, unsafe.Sizeof(str))
	//注意⚠️:字符串一旦赋值了,字符串就不能修改了:在 Go 中字符串是不可变的。
	//var str1 string = "abc"
	//str1[0] = 'c' //❌ 不可取,不可修改里面的内容
	//字符串的两种表示形式 (1) 双引号, 会识别转义字符 (2) 反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果 【案例演示】
	//方式1
	var str2 string = "测试字符串"
	//方式2
	var str3 string = `
			测试字符串表示形式,
			我是以字符串的原生形式输出,可以实现防止攻击、输出源代码等效果
			var str4 string = "4"
	`
	//字符串拼接方式 "" + "",当一行字符串太长时,需要使用到多行字符串,可以如下处理
	var str5 string = "hello" + "word" + "hello" + "word" + "hello" + "word" +
		"test" + "str"
	fmt.Println(str2, str3, str5)

	println("----指针类型----")
	//基本数据类型,变量存的就是值,也叫值类型。 获取变量的地址,用&,比如: var num int, 获取 num 的地址:&num
	//指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值
	var i int = 10
	//1、ptr是一个指针变量 2、ptr存的是i变量的地址 3、类型是*int
	var ptr *int = &i
	fmt.Printf("指针存储的值:%v, 类型:%T, 占内存字节数:%d, 指针存储地址指向的值:%d, 指针的地址:%v \n", ptr, ptr, unsafe.Sizeof(ptr), *ptr, &ptr)

	println("-----基本数据类型的相互转换----")
	基本数据类型的相互转换///
	//Golang 和 java / c 不同,Go 在不同类型的变量之间赋值时需要显式转换。也就是说 Golang 中数 据类型不能自动转换。
	var int_1 int = 100
	var float1 float32 = float32(int_1)
	var int_2 int8 = int8(int_1)

	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", float1, float1, unsafe.Sizeof(float1))
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", int_2, int_2, unsafe.Sizeof(int_2))
	//在转换中,比如将 int64 转成 int8 【-128---127】 ,编译时不会报错,只是转换的结果是按 溢出处理,和我们希望的结果不一样。 因此在转换时,需要考虑范围.
	var int_3 int64 = 999
	var int_4 int8 = int8(int_3) //转换的时候值溢出
	fmt.Printf("值:%v, 类型:%T, 占内存字节数:%d \n", int_4, int_4, unsafe.Sizeof(int_4))

	//基本类型和string互转
	//方式 1:fmt.Sprintf("%参数", 表达式)
	var number1 int = 999
	var number2 float64 = 999.999
	var bool_1 bool = false
	var byte_1 byte = 'a'
	var str_1 string

	str_1 = fmt.Sprintf("%d", number1)
	fmt.Printf("1、转换后的值:%v, 类型:%T, 占内存字节数:%d \n", str_1, str_1, unsafe.Sizeof(str_1))

	str_1 = fmt.Sprintf("%f", number2)
	fmt.Printf("2、转换后的值:%v, 类型:%T, 占内存字节数:%d \n", str_1, str_1, unsafe.Sizeof(str_1))

	str_1 = fmt.Sprintf("%t", bool_1)
	fmt.Printf("3、转换后的值:%v, 类型:%T, 占内存字节数:%d \n", str_1, str_1, unsafe.Sizeof(str_1))

	str_1 = fmt.Sprintf("%c", byte_1)
	fmt.Printf("4、转换后的值:%v, 类型:%T, 占内存字节数:%d \n", str_1, str_1, unsafe.Sizeof(str_1))
	//方式 2:使用 strconv 包的函数
	var number4 int32 = 888
	var number5 float64 = 888.888
	var bool_2 bool = false

	str_1 = strconv.FormatInt(int64(number4), 10)
	fmt.Printf("5、转换后的值:%v, 类型:%T, 占内存字节数:%d \n", str_1, str_1, unsafe.Sizeof(str_1))

	//FormatFloat(f float64, fmt byte, prec, bitSize int),参数依次表示为转换的值、转换的格式、保留小数后多少位、是转换成float64还是float32
	str_1 = strconv.FormatFloat(number5, 'f', 2, 64)
	fmt.Printf("6、转换后的值:%v, 类型:%T, 占内存字节数:%d \n", str_1, str_1, unsafe.Sizeof(str_1))

	str_1 = strconv.FormatBool(bool_2)
	fmt.Printf("7、转换后的值:%v, 类型:%T, 占内存字节数:%d \n", str_1, str_1, unsafe.Sizeof(str_1))

	//string 类型转基本数据类型
	var str_2 string = "true"
	var bool_3 bool

	//strconv.ParseBool返回两个值, _标识忽略返回的第二个值
	bool_3, _ = strconv.ParseBool(str_2)
	fmt.Printf("8、转换后的值:%v, 类型:%T, 占内存字节数:%d \n", bool_3, bool_3, unsafe.Sizeof(bool_3))
	//	strconv.ParseFloat()同理
	//	strconv.ParseInt()同理
	//	strconv.ParseUint()同理

	//注意⚠️事项:在将 String 类型转成 基本数据类型时,要确保 String 类型能够转成有效的数据
	//比如 我们可以 把 "123" ,转成一个整数,但是不能把 "hello" 转成一个整数,如果这样做,Golang 直接将其转成 0 , 其它类型也是一样的道理. float => 0 bool => false
	var str_4 string = "hello"
	var int_5 int64
	int_5, _ = strconv.ParseInt(str_4, 10, 64)
	fmt.Printf("9、转换后的值:%v, 类型:%T, 占内存字节数:%d \n", int_5, int_5, unsafe.Sizeof(int_5))

}

运行结果

----byte类型----:10, 类型:uint8, 占内存字节数:1 
----int类型----:20, 类型:int, 占内存字节数:8:21, 类型:int8, 占内存字节数:1:22, 类型:int16, 占内存字节数:2:23, 类型:int32, 占内存字节数:4:24, 类型:int64, 占内存字节数:8 
----float类型----:30.237488, 类型:float32, 占内存字节数:4:21.23748734872346, 类型:float64, 占内存字节数:8 
----字符类型----:115, 类型:int, 占内存字节数:8, 显示信息=s 
值:21271, 类型:int, 占内存字节数:8, 显示信息=----布尔类型----:true, 类型:bool, 占内存字节数:1 
结束循环, i=  10
----string 类型----:测试字符串, 类型:string, 占内存字节数:16 
测试字符串 
                        测试字符串表示形式,
                        我是以字符串的原生形式输出,可以实现防止攻击、输出源代码等效果
                        var str4 string = "4"
         hellowordhellowordhellowordteststr
----指针类型----
指针存储的值:0x14000126050, 类型:*int, 占内存字节数:8, 指针存储地址指向的值:10, 指针的地址:0x14000120020 
-----基本数据类型的相互转换----:100, 类型:float32, 占内存字节数:4:100, 类型:int8, 占内存字节数:1:-25, 类型:int8, 占内存字节数:1 
1、转换后的值:999, 类型:string, 占内存字节数:16 
2、转换后的值:999.999000, 类型:string, 占内存字节数:16 
3、转换后的值:false, 类型:string, 占内存字节数:16 
4、转换后的值:a, 类型:string, 占内存字节数:16 
5、转换后的值:888, 类型:string, 占内存字节数:16 
6、转换后的值:888.89, 类型:string, 占内存字节数:16 
7、转换后的值:false, 类型:string, 占内存字节数:16 
8、转换后的值:true, 类型:bool, 占内存字节数:1 
9、转换后的值:0, 类型:int64, 占内存字节数:8 

指针相关图示

在这里插入图片描述

标识符

概念

Golang 对各种变量、方法、函数等命名时使用的字符序列称为标识符 ,凡是自己可以起名字的地方都叫标识符。

标识符的命名规则

  1. 由 26 个英文字母大小写,0-9 ,_ 组成
  2. 数字不可以开头。var num int //ok var 3num int //error
  3. Golang 中严格区分大小写。
  4. 在 golang 中,num 和 Num 是两个不同的变量 (var num int

,var Num int )

  1. 标识符不能包含空格。
  2. 下划线"_"本身在 Go 中是一个特殊的标识符,称为空标识符。可以代表任何其它的标识符,但

是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用

  1. 不能以系统保留关键字作为标识符(一共有 25 个),比如 break,if 等等…
保留关键字

在这里插入图片描述

预留关键字

在这里插入图片描述

运算符

运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等

算数运算符一览表

在这里插入图片描述
在这里插入图片描述

package main

import (
	"fmt"
)

func main() {
	var num_0 int = 100
	var num_1 int = 100
	var num_2 int = num_1 + num_0/num_0*num_1
	println(num_2)

	// 演示 % 的使用
	//看一个公式 a % b = a - a / b * b
	fmt.Println("10%3=", 10%3)
	fmt.Println("-10%3=", -10%3)
	fmt.Println("10%-3=", 10%-3)
	fmt.Println("-10%-3=", -10%-3)

	//i++, i--
	var i_0 int8 = 0
	i_0++
	var i_1 int8 = 0
	i_1--
	fmt.Printf("i_0 = %d, i_1 = %d \n", i_0, i_1)
	//Golang 的自增自减只能当做一个独立语言使用时,不能这样使
	/**
	var i_3 int = i_0 ++    //❌ 错误用法
	if i_0 ++ > 1{}    //❌ 错误用法
	*/
	
}

关系运算符

在这里插入图片描述

细节说明
  1. 关系运算符的结果都是 bool 型,也就是要么是 true,要么是 false。
  2. 关系运算符组成的表达式,我们称为关系表达式: a > b
  3. 比较运算符"=="不能误写成 “=” !!

逻辑运算符

用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个 bool 值
在这里插入图片描述

1) &&也叫短路与如果第一个条件为 false,则第二个条件不会判断,最终结果为 **false **

  1. ||也叫短路或:如果第一个条件为 true,则第二个条件不会判断,最终结果为 true
  package main


  func main() {

	//逻辑运算符
	var number_0 int8 = 10
	var number_1 int8 = 15

	if number_1 == 11 || number_0 < 10 {
		println("我是1")
	} else if number_1 == 15 && number_0 == 10 {
		println("我是2")
	} else if !(number_1 == 15) {
		println("我是3")
	}

  }

赋值运算符

在这里插入图片描述
在这里插入图片描述

位运算符

位运算符这边涉及到计算机相关的知识,忘记的可以补习一下二、八、10、16进制以及原码、反码、补码相关的知识
相关链接:https://blog.csdn.net/asd1358355022/article/details/127898198?spm=1001.2014.3001.5501

在这里插入图片描述

其他运算符

在这里插入图片描述

特别说明(三元运算符)

在这里插入图片描述
在这里插入图片描述

运算符优先级

在这里插入图片描述

键盘输入语句

在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。

fmt 包的 fmt.Scanln() 或者 fmt.Scanf()

函数信息
在这里插入图片描述
在这里插入图片描述

代码示例

package main

import "fmt"

func main() {
    var name string
    var age int
    var address string
    
    //方式1:fmt.Scanln
    fmt.Println("请输入姓名")
    fmt.Scanln(&name)
    
    fmt.Println("请输入年龄")
    fmt.Scanln(&age)
    
    fmt.Println("请输入地址")
    fmt.Scanln(&address)
    
    fmt.Printf("姓名:%v, 年龄:%v, 地址:%v   \n", name, age, address)
    //方式2:fmt.Scanf
    println("----------------------")
    var name_1 string
    var age_1 int
    var address_1 string
    println("请输入你的姓名、年龄、地址,依次按照空格隔开")
    fmt.Scanf("%s %d %s", &name_1, &age_1, &address_1)
    fmt.Printf("姓名:%v, 年龄:%v, 地址:%v   \n", name_1, age_1, address_1)

}

运行结果

请输入姓名
测试
请输入年龄
18
请输入地址
北京朝阳区
姓名:测试, 年龄:18, 地址:北京朝阳区   
----------------------
请输入你的姓名、年龄、地址,依次按照空格隔开
测试 18 北京朝阳区
姓名:测试, 年龄:18, 地址:北京朝阳区   


程序流程控制

在程序中,程序运行的流程控制决定程序是如何执行的,是我们必须掌握的,主要有三大流程控制语句。分为:顺序控制、分支控制、循环控制。

  • 顺序结构:代码从上往下依次执行
  • 分支结构:根据不同的条件,执行不同的语句
  • 循环结构: 根据指定的条件,重复执行某段代码。

顺序流程

程序从上到下逐行地执行,中间没有任何判断和跳转。
一个案例说明,必须下面的代码中,没有判断,也没有跳转.因此程序按照默认的流程执行,即顺序控制。
如下图所示,程序自上而下执行
在这里插入图片描述

执行流程图
在这里插入图片描述

分支控制

分支语句的作用就是满足判断条件进入代码块中执行相应的功能

if else流程控制
Golang 中规定与if匹配的{必须与if和表达式位于同一行,否则会发生编译错误。同样的,else也必须上一个分支的}位于同一行。表达式两边可以省略()。 分为单分支语句、双分支语句、多分支语句

switch case流程控制
除了if关键值,Golang 中还提供了switch语句对大量的值和表达式进行判断,除了支持数值常量,Golang 的 switch 还能对字符串、表达式等复杂情况进行处理。

  1. switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上到下逐一测

试,直到匹配为止。

  1. 匹配项后面也不需要再加 break

**switch 和 if 的比较 **
总结了什么情况下使用 switch ,什么情况下使用 if

  1. 如果判断的具体数值不多,而且符合整数、浮点数、字符、字符串这几种类型。建议使用 **swtich **

语句,简洁高效。

  1. 其他情况:对区间判断和结果为 **bool **类型的判断,使用 if,if 的使用范围更广

代码示例

package main

import "fmt"

func main() {

	println("-------if else流程控制------")
	//流程控制
	num := 10

	//单分支语句
	if num <= 10 {
		//满足条件进入流程
		fmt.Println("单分支测试")
	}

	//双分支语句
	if num > 10 {
		fmt.Println("双分支测试01")
	} else {
		fmt.Println("双分支测试02")
	}

	//多分支语句,注意⚠️:双分支语句或者多分支语句执行后只会进入到一个流程当中,代码由上而下执行,只要满足即出流程不会就算是其他分支满足条件也不会进入到分支里
	if num > 10 {
		fmt.Println("多分支测试01")
	} else if num == 10 {
		fmt.Println("多分支测试02")
	} else {
		fmt.Println("多分支测试03")
	}

	//嵌套语句(在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分 支外面的分支结构称为外层分支。)
	num_01 := 20
	if num > 10 {
		fmt.Println("多分支测试04")
	} else if num == 10 {
		if num_01 > 20 {
			fmt.Println("嵌套分支测试01")
		} else if num_01 == 20 {
			fmt.Println("嵌套分支测试02")
		}
		fmt.Println("分支测试05")
	}

	println("-------switch case流程控制------")
	//switch case流程控制
	currentTemperature := 25
	switch currentTemperature {
	case 10:
		fmt.Println("当前天气凉")
	case 25:
		fmt.Println("当前天气温暖~")
	case 40:
		fmt.Println("当前天气热死了!")
	default:
		//以上条件都不符合才会进入这里
		fmt.Println("这鬼天气多变!")
	}

}

运行结果
如下所示,每一种分支只会在满足条件进入到最先满足条件的分支里执行功能

-------if else流程控制------
单分支测试
双分支测试02
多分支测试02
嵌套分支测试02
分支测试05
-------switch case流程控制------
当前天气温暖~

循环控制

Golang 的循环体仅提供了for关键字,没有其他语言中提供的while或者do-while形式
语法格式
for 循环变量初始化; 循环条件; 循环变量迭代 {
循环操作(语句)
}

package main

import "fmt"

func main() {

	//简单示例,循环10次
	for i := 0; i < 10; i++ {
		fmt.Println("循环次数 i = ", i)
	}

	//上述还可以这样写
	j := 0
	for j < 10 {
		fmt.Println("循环次数 j = ", j)
		j++
	}


    	
}


运行结果

循环次数 i =  0
循环次数 i =  1
循环次数 i =  2
循环次数 i =  3
循环次数 i =  4
循环次数 i =  5
循环次数 i =  6
循环次数 i =  7
循环次数 i =  8
循环次数 i =  9
循环次数 j =  0
循环次数 j =  1
循环次数 j =  2
循环次数 j =  3
循环次数 j =  4
循环次数 j =  5
循环次数 j =  6
循环次数 j =  7
循环次数 j =  8
循环次数 j =  9

跳转控制(break/continue/goto)

  • break:满足条件终止循环
  • continue:满足条件跳过此次循环进入下次循环
  • goto:跳转到指定的标签
    • Go 语言的 goto 语句可以无条件地转移到程序中指定的行。
    • goto 语句通常与条件语句配合使用。可用来实现条件转移,跳出循环体等功能。
    • 在 Go 程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序

都产生困难

  • return:结束次方法或者代码块的运行(言外之意:到这里就可以了,不能继续往下走了)
package main

import "fmt"

func main() {
    println("------break测试-----")
	k := 0
	for { //等价于 for ; ;
		if k >= 10 {
			//退出循环
			break
		}
		fmt.Println("循环次数 k = ", k)
		k++
	}

    /continue测试///
	println("------continue测试-----")
	l := 0
	for l < 10 {
		if l == 2 {
			fmt.Println("我是continue测试, l = ", l)
			l++
			continue
		}
		fmt.Println("循环测试, l = ", l)
		l++
	}


    /goto测试///
	println("------goto测试-----")
	flag := false
	if flag == false {
		goto label_01
	}
	println("------goto测试----1-----")
	println("------goto测试----2-----")

	label_01: //跳转标识,上述输出不会打印
	println("------goto测试----3-----")
	println("------goto测试----4-----")

    /return测试///
	println("------return测试-----")
	returnTestNum := 0

	if returnTestNum == 0 {
		println("-----到此为止了!-----")
		return
	}
	println("-----执行动作1-----")
	println("-----执行动作2-----")

	
	

}

运行结果

------break测试-----
循环次数 k =  0
循环次数 k =  1
循环次数 k =  2
循环次数 k =  3
循环次数 k =  4
循环次数 k =  5
循环次数 k =  6
循环次数 k =  7
循环次数 k =  8
循环次数 k =  9
------continue测试-----
循环测试, l =  0
循环测试, l =  1
我是continue测试, l =  2
循环测试, l =  3
循环测试, l =  4
循环测试, l =  5
循环测试, l =  6
循环测试, l =  7
循环测试, l =  8
循环测试, l =  9
------goto测试-----
------goto测试----3-----
------goto测试----4-----
------return测试-----
-----到此为止了!-----

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

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

相关文章

[附源码]计算机毕业设计JAVA高校贫困生认定系统

[附源码]计算机毕业设计JAVA高校贫困生认定系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM myba…

列表的嵌套--Python

#列表的嵌套&#xff1a;在每一个列表中都包含其他列表元素 #获取李四所在列表的值? #获取李四所在的子列表索引&#xff0c;并通过索引获取改子列表值 name_list [[小明,小红,小绿],[Tom,Lily,Rose],[张三,李四,王五]] print(name_list[2]) #在从子列表中通过李四所在的索引…

[翻译] 使用FXGL创建一个非常基本的游戏

游戏要求 首先&#xff0c;让我们为我们的简单游戏定义一些要求: 一个600x600的窗口。屏幕上的玩家&#xff0c;由蓝色矩形表示。可以通过按键盘上的W、S、A或D来移动玩家。UI由一行文本表示。当玩家移动时&#xff0c;UI文本会更新以显示玩家在其生命周期内移动了多少像素。 …

今天给在家介绍一篇基于jsp的旅游网站设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

zookeeper报错length is greater than jute.maxbuffer=1048575

1、场景 最近在给上云项目部署系统&#xff0c;通过压测都已经正式上生产后发现kafka存在异常错误&#xff0c;经排查发现zookeeper也存在错误&#xff0c;怀疑kafka的问题可能是由于zk异常到的&#xff0c;报错如下 2022-11-17 06:26:43,052 [myid:] - WARN [NIOWorkerThr…

HTML学生个人网站作业设计:游戏网站设计——原神首页 1页 带轮播图

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 游戏官网 | 游戏网站 | 电竞游戏 | 游戏介绍 | 等网站的设计与制作 | HTML期末大学生网页设计作业&#xff0c;Web大学生网页 HTML&#xff1a;结构 …

Burpsuite简介及MIME上传绕过实例

目录预备知识1.了解burpsuite2.了解服务端MIME类型检测实验目的实验环境实验步骤一使用Burpsuite的代理功能Target模块实验步骤二使用burpsuite上传绕过服务端MIME类型检测预备知识 1.了解burpsuite Burp Suite是用于攻击web应用程序的集成平台。包含了许多工具&#xff0c;并…

[附源码]Python计算机毕业设计 学生宿舍管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

我们与元宇宙的距离

元宇宙的发展是一个循序渐进的过程&#xff0c;需要经过初始阶段、规划阶段、系统阶段和优化阶段。当前&#xff0c;虽然已经有许多元宇宙完成了搭建&#xff0c;但都是针对单一特定场景的模拟仿真&#xff0c;并且没有实现全面的推广应用&#xff0c;因此我们仍处于元宇宙的初…

浅析多通道接收单元噪声系数的测试

之前一个朋友要测试低噪声放大器(LNA)的噪声系数&#xff0c;但是声称遇到一些麻烦。LNA噪声系数的测试采用Y因子法非常简便&#xff0c;校准完成后直接连接待测件即可测试&#xff0c;可操作性非常强。麻烦在哪里呢&#xff1f; 原来待测件是一个含有四个通道的接收模块&…

2023年三大网络安全威胁不容忽视

2022年已进入尾声&#xff0c;降低数字化风险、增强安全防御能力依然是众多企业组织数字化发展中的重要需求和目标。随着技术的不断进步&#xff0c;网络攻击者的攻击成本不断降低&#xff0c;同时攻击方式更加先进&#xff0c;美国《福布斯》网站在近日的报道中列出了2023年值…

Zoho 如何使用低代码 #1 - 赋予人力资源以技术实力

Zoho 为客户提供了一套跨功能产品&#xff0c;从运行简单的调查到简化复杂的企业组织职能&#xff0c;Zoho 几乎提供了企业的业务运行所需的一切。 组织在新的规范和挑战中不断进行扩展&#xff0c;这就不断需要构建可定制的解决方案。这就是为什么除了现成的应用程序之外&…

第1关:ZooKeeper初体验

ZooKeeper安装方法 由于本实验环境已经安装ZooKeeper并配置&#xff0c;下面主要讲述一般环境的安装方法。 可以从ZooKeeper的官方网站上下载稳定版&#xff0c;下载地址如下&#xff1a;Apache ZooKeeper 下载后&#xff0c;利用tar命令将压缩包解压到/opt/zookeeper-3.4.1…

实验31:温湿度传感器实验

本实验也比较简单 用LCD1602显示温湿度传感器返回的温湿度值 本专栏就要结尾了 希望对大家有一定的帮助 学习就是一点一滴的 01 硬件电路设计 整体电路图 重点还是接口: 因为最后相放一个学生做的大创为结尾彩蛋,所以这里就不再添加报警灯什么的额外操作了 每一个实验…

OVS 和 OVS-DPDK 对比

OVS 目前有两种比较突出的架构&#xff0c;一种是原生的 OVS 架构&#xff08;使用 kernel 作为 datapath&#xff09;&#xff0c;一种是基于 DPDK 的架构&#xff08;使用用户空间作为 datapath&#xff09;。 原生 OVS 原生 OVS 架构如下所示&#xff0c;主要包含两个组件…

冷启动问题分析与解决办法

1、什么是冷启动问题&#xff1f; 在缺乏有价值数据的时候&#xff0c;如何有效地满足业务需求的问题&#xff0c;就是“冷启动问题”。为了沟通方便&#xff0c;下面统一从推荐系统的角度来讲“冷启动问题”&#xff0c;其他业务场景同理。 冷启动问题是机器学习系统中十分常…

完成Zookeeper集群部署

目录一、实验介绍1.1实验内容1.2实验知识点1.3实验环境1.4实验资源1.5实验步骤清单二、实验架构三、实验环境准备四、实验步骤4.1部署Zookeeper集群4.1.1配置hosts文件4.1.2安装Zookeeper软件(master)4.1.3修改zookeeper配置文件4.1.4配置Zookeeper集群4.2验证Zookeeper集群4.2…

python419社区疫情综合管理系统django

目 录 摘 要 I 目 录 I 第1章 绪论 1 1.1课题背景 1 1.2目的和意义 1 1.3研究现状 2 1.4研究内容 3 第2章 关键技术研究 4 开发语言&#xff1a;Python 框架&#xff1a;django Python版本&#xff1a;python3.7.7 数据库&#xff1a;mysql 数…

js的闭包例题

1、垃圾回收 &#xff08;1&#xff09;全局变量不会被回收 &#xff08;2&#xff09;局部变量会被回收&#xff0c;函数执行结束&#xff0c;函数内部东西会被销毁 &#xff08;3&#xff09;某作用域中的某个变量还在被另一个作用域引用就不会被回收 var a[]; for(var i 0…

docker安装部署实战详细手册

文章目录一、docker介绍1.什么是docker2.为什么使用docker二、docker架构三、docker安装1.安装2.卸载结尾一、docker介绍 1.什么是docker Docker 是一个开源的容器引擎&#xff0c;它有助于更快地交付应用。Docker 可将应用程序和基础设施层隔离&#xff0c; 并且能将基础设施…