【Golang第1~3章:基础】如何安装golang、第一个GO程序、golang的基础

介绍

本人是个菜鸡,这个是在B站上看边看视频边做的笔记,这一章是编程语言的基础

有变量、常量、数据类型、指针、标识符、运算符、流程控制,具体请看【文章目录】

配套视频自己去B站里面搜【go语言】,最高的播放量就是

里面的注释我写的可能不太对,欢迎大佬们指出╰(°▽°)╯

(一).安装Golang

1.下载Golang

https://golang.google.cn/dl/

2.设置golang插件地址为国内

打开cmd

输入 go env -w GOPROXY=https://goproxy.cn,direct 设置插件地址为国内CDN七牛云

查看地址是否更改

go env

在这里插入图片描述

go env -w GOBIN=D:/apps/Go/bin

关闭GO111MODULE管理工具,这样引入包的时候会默认获取GOPATH的路径进行引入

go env -w GO111MODULE=off

打开电脑环境变量修改GOPATH

在这里插入图片描述

  • GOROOT:GOROOT就是Go的安装目录,(类似于java的JDK)

  • GOPATH:GOPATH是我们的工作空间,保存go项目代码和第三方依赖包


3.Vscode插件安装

按住Ctrl+Shift+P 输入Go:Install/Update Tools








(二).第一个go程序


打印字符串,链接符号,单行注释,多行注释,变量,字符串

package main

import "fmt"

func main() {
	var hello = "你好!!"
	fmt.Println("hello !!!")
	fmt.Println(hello)
	fmt.Println("你好:" + "hello" + hello)

	// 反引号可以强制转换为字符串
	str := `
	sdfjalsdjf
	sdf
	func 
	var hello = "你好!!"
	fmt.Println("hello !!!")
	\sdf \n sdfinesl
	`
	fmt.Println(str)

}

// 单行注释
/*
多行注释
*/

字符串的两种表示形式

  1. 双引号, 会识别转义字符
  2. 反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果







(三).基础


1.变量

三种声明方式

package main
 
import "fmt"
 
func main() {
    var i int  = 10 	// var 变量名 类型 = 值
    var j = 1.2 		// var 变量名 = 值
 
    name := "szc" 		// 变量名 := 值,自动推导类型
 
    fmt.Println("i = ", i, ", j = " , j , ", name = ", name)
}

一次声明多个变量,变量名和值一一对应

var a, sex, b = 1, "male", 7
a, sex, b := 2, "male", 4

函数外声明全局变量

var (
    n1 = 1
    n2 = 2
    n3 = 3
)
 
var n4 = "n4"
 
func main() {
    fmt.Println("n1 = ", n1, ", n2 = ", n2, "n3 = ", n3, ", n4 = ", n4)
}

变量声明后必须使用,而且不能隐式改变类型(int转float)


2.常量

常量必须赋初值,而且不可更改

    const tax int = 1
    const name_ = "szc"
    const b = 4 / 2
 
//    const b_ = getVal() 	// 编译期值不确定
//    num := 1
//    const b_ = num / 2  	// 编译期值不确定
//    const tax_0 int 	// 必须赋初值
//    tax = 2	 // 不可修改

常量只能修饰布尔、数值、字符串类型

也可以这么声明常量,可以在函数里面声明

const (
    a = iota  //0
    b = iota  //1
    c = iota  //2
    d,e = iota,iota  //3 3
)
fmt.Println(a, b, c, d, e) // 0 1 2 3 3 依次加1

上面b和c可以不写= iota,但是a必须写


3.数据类型

在这里插入图片描述

  • 数值型中的int32又称为rune,可保存一个unicode码点。int和uint的大小和操作系统位数一样,32位OS(系统)则为4字节,64位OS则为8字节。浮点数默认64位,整数默认int。
  • float32 精确度为小数点后6位,float64为14位;

值类型与引用类型

值类型:基本数据类型、数组、结构体。变量直接存储值,通常存储于栈中,函数传参时使用值传递

引用类型:指针、切片、映射、管道、接口等。变量存储的是值的地址,通常存储于堆中,会发生GC,函数传参时使用引用传递。

函数参数的两种传递方式

  1. 值传递
  2. 引用传递

不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是,值传递的是值的拷贝,引用传递的是地址的拷贝,一般来说,地址拷贝效率高,因为数据量小,而值拷贝决定拷贝的数据大小,数据越大,效率越低。


查看变量类型

查看变量类型:

a, sex:= 2, "male"
 
fmt.Printf("a的类型:%T,sex的类型:%T\n", a, sex)

查看变量占用内存大小时,先导入unsafe和fmt包

import (
    "fmt"
    "unsafe"
)

再调用unsafe.Sizeof函数就行

fmt.Printf("a占用内存大小:%d, sex占用内存大小:%d", unsafe.Sizeof(a), unsafe.Sizeof(sex))

字符与字符串

输出字符时,需要格式化输出,否则会输出的它的ascii值

c1 := 's'
c2 := '0'
 
fmt.Println("c1 = ", c1, ", c2 = ", c2)
fmt.Printf("c1 = %c, c2 = %c\n", c1, c2)

输出汉字和对应unicode码值

c3 := '宋'
fmt.Printf("c3 = %c, 对应unicode码值: %d\n", c3, c3)

跨行字符串,用`包住

var s = `
拜仁慕尼黑来自德甲。
它在今年欧冠八分之一淘汰赛上首回合客场3:0完胜切尔西。
`

多行拼接字符串,要在+后面换行,而不是字符串后面

s1 := "abc" +
 " def" + "hij"

数据类型默认值

%d表示为十进制,%v是变量的原值输出,%f是浮点输出,%T是数据类型

	var a int          //0
	var b float32      //0
	var c float64      //0
	var isMarried bool //false
	var name string    //空的
	//%d表示为十进制,%v是变量的原值输出,%f是浮点输出,%T是数据类型
	fmt.Printf("a=%d,b=%f,c=%f,isMarried=%v,name=%v", a, b, c, isMarried, name)
	fmt.Printf("a=%d,b=%v,c=%v,isMarried=%v,name=%v", a, b, c, isMarried, name)

数据相互转换

不同数据类型之间必须显式类型转换

a1 := 1.2
a2 := int(a1)
fmt.Println("a2 = ", a2)

var i int32 = 100
//希望将i => float
var n1 float32 = float32(i)
var n2 int8 = int8(i)
var n3 int64 = int64(i) //低精度->高精度
fmt.Printf("i=%v n1=%v n2=%v n3=%v", i, n1, n2, n3)

如果范围大转换成范围小的,可能会发生精度损失,以下是例子:

var i1 int32 = 12
var i2 int8
var i3 int8
 
i2 = int8(i1) + 127 // 编译通过,但是运行时溢出,得不到想要结果
i3 = int(i1) + 128 // 直接溢出,编译错误
 
fmt.Println("i2 = ", i2)
基本数据类型转换为string类型

在程序开发中,我们经常将基本数据类型转成 string,或者将 string 转成基本数据类型。


方式 1:fmt.Sprintf(“%参数”, 表达式)
func main() {
	var num1 int = 99
	var str string //空的str
	//把num1转换为string类型
	str = fmt.Sprintf("%d", num1) //%d表示为十进制
	fmt.Printf("str的类型是%T , str的原值是%q\n", str, str)

	var num2 float64 = 23.456
	str = fmt.Sprintf("%f", num2)                   //%f为浮点数
	fmt.Printf("str的类型是%T , str的原值是%v\n", str, str) //%v原值输出

	var b bool = true
	str = fmt.Sprintf("%t", b)                      //%t布尔值true或false
	fmt.Printf("str的类型是%T , str的原值是%q\n", str, str) //%q表示字符串输出并加上引号,同%v

	var myChar byte = 'h'
	str = fmt.Sprintf("%c", myChar) //%c表示为字符,转换为字符串
	fmt.Printf("str的类型是%T , str的原值是%q\n", str, str)
}

输出为

str的类型是string , str的原值是"99"
str的类型是string , str的原值是23.456000   //这个没有按%q输出,所以没有双引号
str的类型是string , str的原值是"true"
str的类型是string , str的原值是"h"

方式 2:使用 strconv 包的函数

用之前先导入strconv包

import (
    "fmt"
    "strconv"
)

然后调用函数进行转换

	var num3 int = 99
	var num4 float64 = 23.456
	var b2 bool = true
	str = strconv.FormatInt(int64(num3), 10)
	fmt.Printf("str的类型是%T , str的原值是%q\n", str, str)

	// strconv.FormatFloat(num4, 'f', 10, 64)
	// 说明: 'f' 转换的格式,10:表示小数点保留10位,64:表示这个小数是float64
	str = strconv.FormatFloat(num4, 'f', 10, 64)
	fmt.Printf("str的类型是%T , str的原值是%q\n", str, str)

	str = strconv.FormatBool(b2)
	fmt.Printf("str的类型是%T , str的原值是%q\n", str, str)
string类型转换为基本数据类型
func main() {
	var str string = "true"
	var b bool
	//	b, _ = strconv.ParseBool(str)
	// 说明
	// 1. strconv.ParseBool(str)函数会返回两个值(value bool, err error)
	// 2. 因为我只想获取到value bool ,不想获取err 所以使用 _ 忽略
	b, _ = strconv.ParseBool(str)
	fmt.Printf("b的数据类型是%T , b的值为%v\n\n", b, b)

    
	var str2 string = "12331"
	var n1 int64
	var n2 int
	n1, _ = strconv.ParseInt(str2, 10, 64)
	n2 = int(n1)
	fmt.Printf("n1的数据类型是%T , n1的值为%v\n", n1, n1)
	fmt.Printf("n2的数据类型是%T , n2的值为%v\n\n", n2, n2)

    
	var str3 string = "12331.1321"
	var f1 float64
	f1, _ = strconv.ParseFloat(str3, 64)
	fmt.Printf("f1的数据类型是%T , f1的值为%v\n", f1, f1)
}

输出为

b的数据类型是bool , b的值为true

n1的数据类型是int64 , n1的值为12331
n2的数据类型是int , n2的值为12331

f1的数据类型是float64 , f1的值为12331.1321

说明

在这里插入图片描述

string 转基本数据类型的注意事项

在将 String 类型转成 基本数据类型时,要确保 String 类型能够转成有效的数据,比如 我们可以 把 “123” , 转成一个整数,但是不能把 “hello” 转成一个整数,如果这样做,Golang 直接将其转成 0 , 其它类型也是一样的道理. float => 0 bool => false

在这里插入图片描述


指针

  1. 基本数据类型,变量存的就是值,也叫值类型

  2. 获取变量的地址,用&,比如:var num int,获取num的地址: &num

  3. 指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值 如:

    var ptr *int = &num   // ptr是指针变量  ptr的类型为 *int   值为&num
    
  4. 获取指针类型所指向的值,使用:,比如: var ptr int,使用ptr获取p指向的值

func main() {

	//基本数据类型在内存布局
	var i int = 10
	//i的地址是 &i
	fmt.Print("i的内存地址是:", &i, "\n\n")

	//下面var ptr *int = &i
	//1.ptr 是一个指针的变量
	//2.ptr 的类型 *int
	//3.ptr 本身的值&i
	var ptr *int = &i
	fmt.Printf("ptr的值是%v\n", ptr)
	fmt.Printf("ptr内存地址:%v\n", &ptr)
	fmt.Printf("ptr取本身的i值:%v\n", *ptr)
}

在这里插入图片描述


值类型和引用类型

  • 值类型:变量直接存储值,内存通常在栈中分配

    示意图:
    在这里插入图片描述

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

    示意图:
    在这里插入图片描述

  • 内存的栈区和堆区

    示意图:
    在这里插入图片描述


4.标识符


标识符概念

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

标识符的命名规则

  1. 由26个英文字母大小写, 0-9, _组成

  2. 数字不可以开头。

  3. Golan中严格区分大小写

  4. 标识符不能包含空格

  5. 下划线”_”本身在Go中是一个特殊的标识符,称为空标识符。可以代表任何其它的标识符,但是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用

  6. 不能以系统保留关键字作为标识符,比如 break,if 等等


系统保留关键字

下面列出25个Go语言的关键字或保留字:

breakdefaultfuncinterfaceselect
casedefergomapstruct
chanelsegotopackageswitch
constfallthroughifrangetype
continueforimportreturnvar

除了以上介绍的这些关键字,Go 语言还有 36 个预定义标识符,其中包含了基本类型的名称和一些基本的内置函数,见下表:

appendboolbytecapclosecomplexcomplex64complex128uint16
copyfalsefloat32float64imagintint8int16uint32
int32int64iotalenmakenewnilpanicuint64
printprintlnrealrecoverstringtrueuintuint8uintptr

标识符的命名规范

  1. 包名:保持 package的名字和目录保持一致,包名统一使用单数形式,尽量采取有意义的包名,简短,有意义,不要和标准库冲突
  2. 变量名、函数名、常量名:采用驼峰法
  3. 如果变量名、函数名、常量名首字母大写,则可以被其他的包访问;如果首字母小写则只能在本包中使用(注:可以简单的理解成,首字母大写是公有的,首字母是私有的),在 golan没有public, private等关键字
  4. 文件命名:一律采用小写,不用驼峰式,尽量见名思义,看见文件名就可以知道这个文件下的大概内容。
    其中测试文件以_test.go结尾,除测试文件外,命名不出现。


5.运算符


算数运算符

下表列出了所有Go语言的算术运算符。假定 A 值为 10,B 值为 20。

运算符描述实例
+相加A + B 输出结果 30
-相减A - B 输出结果 -10
*相乘A * B 输出结果 200
/相除B / A 输出结果 2
%求余B % A 输出结果 0
++自增A++ 输出结果 11
自减A– 输出结果 9

注:

  1. / 运算符需要保留小数位时需要有浮点型参与运算

  2. % 结果计算公式为: a % b = a - a / b * b

  3. Golang的自增自诚只能当做一个独立语言使用时,不能这样使 b := a++或者b := a–

  4. Golang的++ 和 – 只能写在变量的g后面,不能写在变量的前面,即:只有a++,a–没有++a,–a

  5. Golang的设计者去掉c/java中的自增自诚的容易混淆的写法,让 Galang更加简洁,统一 (强制性的)


关系运算符

下表列出了所有Go语言的关系运算符。假定 A 值为 10,B 值为 20。

运算符描述实例
==检查两个值是否相等,如果相等返回 True 否则返回 False。(A == B) 为 False
!=检查两个值是否不相等,如果不相等返回 True 否则返回 False。(A != B) 为 True
>检查左边值是否大于右边值,如果是返回 True 否则返回 False。(A > B) 为 False
<检查左边值是否小于右边值,如果是返回 True 否则返回 False。(A < B) 为 True
>=检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。(A >= B) 为 False
<=检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。(A <= B) 为 True

逻辑运算符

下表列出了所有Go语言的逻辑运算符。假定 A 值为 True,B 值为 False。

运算符描述实例
&&逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。(A && B) 为 False
||逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False。(A || B) 为 True
!逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。!(A && B) 为 True
  1. &&也叫短路与:如果第一个亲件为 False,则第二个条件不会判断,最终结果为 false
  2. ||叫短路或:如果第一个亲件为true,则第二个条件不会判断,最终结果为true

案例

func test() bool {
	fmt.Println("test...")
	return true
}

func main() {
	var i = 10
	// 短路与
	// 因为 i < 9 为 false,因此后面的test() 和 hello... 都不执行
	// 因为 i > 9 为 true ,结果都为真,所以 test() 和 hello... 都输出
	if i < 9 && test() {
	fmt.Println("hello...")
	}

	// 因为 i < 9 为 false,但是test()为true,因此只执行test()
	// 因为 i > 9 为 ture   所以 test() 不执行,
	if i > 9 || test() {
		fmt.Println("hello...")
	}

赋值运算符

下表列出了所有Go语言的赋值运算符。假定 A 为21

运算符描述实例
=简单的赋值运算符,将一个表达式的值赋给一个左值C = A 将 A 赋值给 C,结果:21
+=相加后再赋值C += A 等于 C = C + A,结果:42
-=相减后再赋值C -= A 等于 C = C - A,结果:21
*=相乘后再赋值C *= A 等于 C = C * A,结果:441
/=相除后再赋值C /= A 等于 C = C / A,结果:21
%=求余后再赋值C %= A 等于 C = C % A,结果:0//不记入计算
<<=左移后赋值C <<= 2 等于 C = C << 2,结果:84
>>=右移后赋值C >>= 2 等于 C = C >> 2,结果:21
&=按位与后赋值C &= 2 等于 C = C & 2,结果:0
^=按位异或后赋值C ^= 2 等于 C = C ^ 2,结果:2
|=按位或后赋值C |= 2 等于 C = C | 2,结果:2
  1. 赋值运算符的运算顺序为:从右往左
  2. 运算符的左边只能是变量,右边可以是变量、表达式、常量

运算符优先级

有些运算符拥有较高的优先级,二元运算符的运算方向均是从左至右。下表列出了所有运算符以及它们的优先级,由上至下代表优先级由高到低:

优先级     运算符
 7      ^ !
 6      * / % << >> & &^
 5      + - | ^
 4      == != < <= >= >
 3      <-
 2      &&
 1      ||
  1. 只有单目运算符、赋值运算符是从右向左运算的。其余都是从左向右
  2. 可以通过使用括号来临时提升某个表达式的整体运算优先级。

位运算符

位运算符对整数在内存中的二进制位进行操作。假定 A 为60,B 为13

运算符描述实例
&按位与运算符”&”是双目运算符。 其功能是参与运算的两数各对应的二进位相与。(A & B) 结果为 12, 二进制为 0000 1100
|按位或运算符”|”是双目运算符。 其功能是参与运算的两数各对应的二进位相或(A | B) 结果为 61, 二进制为 0011 1101
^按位异或运算符”^”是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。(A ^ B) 结果为 49, 二进制为 0011 0001
<<左移运算符”<<”是双目运算符。左移n位就是乘以2的n次方。 其功能把”<<”左边的运算数的各二进位全部左移若干位,由”<<”右边的数指定移动的位数,高位丢弃,低位补0。A << 2 结果为 240 ,二进制为 1111 0000
>>右移运算符”>>”是双目运算符。右移n位就是除以2的n次方。 其功能是把”>>”左边的运算数的各二进位全部右移若干位,”>>”右边的数指定移动的位数。A >> 2 结果为 15 ,二进制为 0000 1111

演示示例:

package main

import "fmt"

func main() {
   var a int = 60     //二进制是:111100  
   var b int = 13     //二进制是:001101

   fmt.Printf("%b\n%d\n",a&b,a&b)    //二进制是:1100,对应的十进制是12。说明&进行的是上下对应位的与操作
   fmt.Printf("%b\n%d\n",a|b,a|b)    //二进制是:111101,对应的十进制是61。说明&进行的是上下对应位的或操作
   fmt.Printf("%b\n%d\n",a^b,a^b)    //二进制是:110001,对应的十进制是49。^位运算符是上下对应位不同时,值为1
    
    
    c := 1 >> 2  //0000 0001 => 0000 0000 = 0
    d := 1 << 2  //0000 0001 => 0000 0100 = 4
    
}

原码,反码,补码

计算机都是以补码运行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QtDR1TJM-1668406607764)(assets/image-20220720204124199.png)]

左移右移运算符示例(实现计算器存储单位):

package main

import "fmt"

const (   
    KB float64 = 1<<(10*iota)      //iota是 const 结构里面,定义常量行数的索引器,每个 const 里面,iota 都从 0 开始
    MB                             //下面是一个省略调用,继承了上面的表达式
    GB
    TB
    PB
)

func main() {
   fmt.Printf("1MB = %vKB\n",MB) 
   fmt.Printf("1GB = %vKB\n",GB)
   fmt.Printf("1TB = %vKB\n",TB)
   fmt.Printf("1PB = %vKB\n",PB)
}
运行结果:
1MB = 1024KB
1GB = 1.048576e+06KB
1TB = 1.073741824e+09KB
1PB = 1.099511627776e+12KB

其他运算符

运算符描述实例
&返回变量存储地址&a; 将给出变量的实际地址。
*指针变量。*a; 是一个指针变量

内存地址和指针的示例:打印变量类型用%T

package main

import "fmt"

func main() {
   var a int = 4
   var b int32
   var c float32
   var ptr *int

   fmt.Printf("a 变量类型为 = %T\n", a )     //输出变量类型%T
   fmt.Printf("b 变量类型为 = %T\n", b )
   fmt.Printf("c 变量类型为 = %T\n", c )

   ptr = &a    
   fmt.Printf("a 的内存地址为 = %p",ptr)     //go里面的内存块地址通常都是用十六进制表示的,因此输出:0x10414020a
   fmt.Printf("*ptr 为 %d\n", *ptr)        //这是个指向a的内存地址的指针,因此输出:4
}

特殊说明

举例说明,如果在 golang 中实现三元运算的效果

在这里插入图片描述


读取控制台数据

调用fmt.Scan等方法即可

var j string
fmt.Scanln(&j) // Scanln读取一行
fmt.Println("j = ", j)

或者指定输入格式

var j string
var m float32
var n bool
 
fmt.Scanf("%d%f%s%t", &i, &m, &j, &n)
fmt.Println("i = ", i, "j = ", j, "m = ", m, "n = ", n)

输入时按空格或回车区分即可


6.流程控制


if-else 流程控制

基本语法

if 表达式1 { // 表达式可以写(),官方不推荐写

 //代码块

} else if 表达式2{ // else if 可省略,不能换行写

 //代码块

} else { // else 可省略,不能换行写

 //代码块

}

在这里插入图片描述


switch分支结构

基本语法

switch 表达式 {

 case 表达式1,表达式2,…… :

 // 语句块1

 case 表达式3,表达式4,…… :

 // 语句块2

 // 多个case,结构同上

 default :

 // 语句块3

}

例子:

	var time int
	fmt.Println("请输入a,b,c,d,e,f,g")
	fmt.Scanf("%c", &time)

	switch time {
	case 'a':
		fmt.Println("星期一")
	case 'b':
		fmt.Println("星期二")

	default:
		fmt.Println("输入有误")
	}

switch 的执行的流程

  1. 先执行表达式,得到值,然后和 case 的表达式进行比较,如果相等,就匹配到,然后执行对应的 case 的语句块,然后退出 switch 控制。
  2. 如果 switch的表达式的值没有和任何的 case 的表达式匹配成功,则执行 default的语句块。
  3. 多个表达式使用逗号间隔

for循环

基本语法

for 循环变量初始化 ;循环条件 ;循环变量迭代 {

//循环操作

}

for  i := 0 ; i < 10 ; i++  {
	//代码块
}

注:Go中没有while,do…while循环,Go语言支持goto跳转,但不支持使用


死循环写法
//写法一
for {
    //循环执行语句
}

//写法二
for ;; {
    //循环执行语句
}

通常和break使用


break终止循环

break用于终止某个语句块的执行,用于中断当前for或跳出switch语句

break 出现在多层嵌套循环中可以使用标签(label)表明要终止哪个循环

for i := 0 ; i < 4 ; i++ {
	for j := 0 ; j < 10 ; j++ {
		if j==2 {
			break  // break  默认会跳出最近的for循环
		}
		fmt.Println("j=",j)
	}
}

输出结果:

j= 0
j= 1
j= 0
j= 1
j= 0
j= 1
j= 0
j= 1

使用标签

label1:
	for i := 0 ; i < 4 ; i++ {
		for j := 0 ; j < 10 ; j++ {
			if j==2 {
				break  label1	// 一旦触发直接终止i的循环
			}
			fmt.Println("j=",j)
		}
		fmt.Println("i=",i)
	}

输出结果:

j= 0
j= 1


continue跳过本次循环

continue用于结束本次循环,在多层嵌套时可用标签跳转,用法同上(break是终止循环,continue是跳过本次循环)


for-range遍历

这是一种同时获取索引和值或键值的遍历方式

在这里插入图片描述

如果我们的字符串含有中文,那么传统的遍历字符串方式,就是错误,会出现乱码。

原因是传统的 对字符串的遍历是按照字节来遍历,而一个汉字在 utf8 编码是对应 3 个字节

如何解决 需要要将 str 转成 []rune 切片.=> 体验一把

在这里插入图片描述


while 和 do…while 的实现

Go 语言没有 while 和 do…while 语法,这一点需要同学们注意一下,如果我们需要使用类似其它语 言(比如 java / c 的 while 和 do…while ),可以通过 for 循环来实现其使用效果

func main() {
	//使用while方式输出10句hello world!
	var i int = 1
	for {
		if i > 10 {
			break
		}
		fmt.Println("hello world", i)
		i++
	}

	//使用do...while方式输出10句hello ok!
	var j int = 1
	for {
		fmt.Println("hello ok!", j)
		j++
		if j > 10 {
			break
		}
	}
}

for 循环是一个无限循环

break 语句就是跳出 for 循环

练习题:打印金字塔
package main

import "fmt"

func main() {
	//使用 for 循环完成下面的案例请编写一个程序,可以接收一个整数,表示层数,打印出金字
	//编程思路
	/*
		//1,打印一个矩形
		***
		***
		***
		//2,打印整个金字塔
		  *		1层1个* | 规律:2 * 层数 -1 | 空格规律:总层数-当前层数
		 ***	2层2个* | 规律:2 * 层数 -1 | 空格规律:总层数-当前层数
		*****	3层3个* | 规律:2 * 层数 -1 | 空格规律:总层数-当前层数
		//3,打印空心金字塔
		  *
		 * *
		*****
	*/

	number := 5
	for i := 1; i <= number; i++ {
		//打印*号前先打印空格
		for n := 1; n <= number-i; n++ {
			fmt.Print(" ")
		}

		fmt.Printf(" ")
		for j := 1; j <= 2*i-1; j++ {
			//判断第一个是打印*号还是空格
			if j == 1 || j == 2*i-1 || i == number {
				fmt.Print("*")
			} else {
				fmt.Print(" ")
			}
		}
		fmt.Println()
	}
}

break引入和快速入门

生成随机数

package main

import (
	"fmt"
	"math/rand"
	"time"
)
func main() {
	//为了生成一个随机数,还需要rand设置一个种子
	//time.Now().Unix() : 返回一个从1970:01:01 的0时0秒到现在的秒数 ,就是一个时间戳
	fmt.Println(time.Now().Unix())
	rand.Seed(time.Now().Unix())
	//如何随机生成1-100
	n := rand.Intn(100) + 1 // [0 100) 不包含100
	fmt.Println(n)
}

生成多个随机数演示break退出

	var conut int = 0
	for {
		rand.Seed(time.Now().UnixNano())
		n := rand.Intn(100) + 1
		fmt.Println(n)
		conut++
		if n == 99 {
			break
		}
	}
	fmt.Println("生成 99 一共使用了", conut)

在这里插入图片描述

break 默认会跳出最近的 for 循环

break 后面可以指定标签,跳出标签对应的 for 循环


跳转控制语句-goto

Go 语言的 goto 语句可以无条件地转移到程序中指定的行。

goto 语句通常与条件语句配合使用。可用来实现条件转移,跳出循环体等功能。

在 Go 程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序 都产生困难。

在这里插入图片描述

跳转控制语句-return

return 使用在方法或者函数中,表示跳出所在的方法或函数




章节目录

【Golang第1~3章:基础】如何安装golang、第一个GO程序、golang的基础

【Golang第4章:函数】Golang包的引用,return语句、指针、匿名函数、闭包、go函数参数传递方式,golang获取当前时间

【Golang第5章:数组与切片】golang如何使用数组、数组的遍历和、使用细节和内存中的布局;golang如何使用切片,切片在内存中的布局

【Golang第6章:排序和查找】golang怎么排序,golang的顺序查找和二分查找,go语言中顺序查找二分查找介绍和案例

【Golang第7章:map】go语言中map的基本介绍,golang中map的使用案例,go语言中map的增删改查操作,go语言对map的值进行排序

【Golang第8章:面向对象编程】Go语言的结构体是什么,怎么声明;Golang方法的调用和声明;go语言面向对象实例,go语言工厂模式;golang面向对象的三大特性:继承、封装、多态

【Golang第9章:项目练习】go项目练习家庭收支记账软件项目、go项目练习客户管理系统项目

【Golang第10章:文件操作】GO语言的文件管理,go语言读文件和写文件、GO语言拷贝文件、GO语言判断文件是否存在、GO语言Json文件格式和解析

【Golang第11章:单元测试】GO语言单元测试

【Golang第12章:goroutine协程与channel管道】GO语言goroutine协程和channel管道的基本介绍、goroutine协

posted @ 2022-11-14 13:57  雪花凌落的盛夏  阅读(42)  评论(0编辑  收藏  举报  来源