【阶段1 Go语言基础】 Day01 变量、字符串、运算符

发布时间 2023-05-30 00:28:37作者: 澐湮

Day01

GO运维开发课程介绍

Go语言基础(10天)
	1 变量 常量 流程控制
	2 数组 切片 map 字符串处理 排序
	3 错误处理 panic recover 函数 递归 匿名函数 作用域 闭包 todolist
	4 包管理 标准包 单元测试
	5 结构体 匿名结构体 匿名嵌套 结构体指针 密码生成 md5 文件操作 
	6 文件操作 copy实现 带缓冲的bufio
	7 接口
	8 并发
	9 网络编程
	10 web rpc 爬虫 模板语法
	
Go语言数据库(2天)
	11 mysql
	12 redis
Go语言前端Web(3天+6天)
	01 html
	02 css
	03 js
	04 vue
	05 vue 
Go语言gin框架+图书管理系统项目(3天+2天)
	01 路由与视图
	02 模板语法
	03 ORM
	04 书籍管理系统
	05 代码拆分 中间件 session cookie 跨域
Go语言Urils项目
	01 项目初始化
	02 初始化-后端1
	03 初始化-后端2
	04 资产管理
	05 资产管理-主机管理-批量上传
	06 资产管理-websocket
	07 资产管理-批量任务
	08 jenkins和gitlab配置
	09 Go调用GitlabAPI接口
	10 应用管理-代码发布
	

初识GO语言

Go语法 2009年发布

Go是一门开放源码的编程语言,可以容易的构建,简单、可靠和高效的软件
开发者使用编程语言的三大分类(执行速度、简易程度、开发难度)
执行速度快、编译速度慢(编译型):C C++
执行速度较慢、编译速度快(解释型)JAVA .NET
执行速度慢、开发难度小(动态脚本)Python PHP

Go语言的三个条件做了平衡:易于开发、快速编译、高效执行

特性

静态类型并具有丰富的内置类型
函数多返回值
错误处理机制
语言层并发
面向对象:使用类型、组合、接口来实现面向对象思想
反射
CGO:用于调用C语言实现的模块
自动垃圾回收
静态编译
易于部署
基于BSD协议完全开放

落地应用场景

# Go语言主要用于服务端开发,其定位是开发大型软件,常用于:
服务器编程:日志处理、虚拟机处理、文件系统、分布式系统等
网络编程:Web应用、API应用、下载应用等
内存数据库
云平台
机器学习
区块链

使用Go开发的项目

Go
Docker
Kubernetes

开源项目列表

# 百科
http://github.com/golang/go/wiki
# 开源项目列表
https://github.com/golang/go/wiki/Projects

编译工具的	   Build Tools
缓存的 		cache
云计算的 	    Cloud Computing
命令行工具的
压缩			 Compression
并发的			Concurrency and Goroutines
配置的文件解析的 Configuration File Parsers
加密的			Cryptocurrency
控制台的		Console User Interface
持续集成		Continuous Integration
数据处理的		Data Processing
自己实现的一些堆栈等

日期处理
开发工具
文档处理 
Email处理

语言机器学习
日志监控

工业中的应用

国外 Google Microsoft Amazon FaceBook
国内 阿里 腾讯 百度 京东、爱奇艺、今日头条、滴滴、美团、B站

环境部署

1) Windows

1 图形界面,下一步安装
2 配置环境变量
	第一种:使用go命令设置
		go env -w GOPATH=D:\GoWork
	第二种:通过windows设置,此电脑--属性--高级系统设置--环境变量
		用户变量
			GOPATH --> D:\GoWork
		系统变量
			GOPROXY --> https://goproxy.cn,direct
			Path --> D:\GoWork\bin
3 创建目录
	D:\GoWork\bin
	D:\GoWork\pkg
	D:\GoWork\src\go_course\day01	

2) Linux

1 解压安装包
	tar -xvf go1.17.11.linux-amd64.tar.gz -C /usr/local
2 配置环境变量
	/etc/profile.d/go.sh
3 创建目录
	mkdir -p ~/go/{bin,pkg,src}
# /etc/profile.d/go.sh
if [[ "x" == "x${GOROOT}" ]]; then
    export GO111MODULE=on
    export GOPROXY=https://goproxy.cn,direct
    export GOROOT=/usr/local/go
    export GOPATH=${HOME}/go
    export PATH=${GOROOT}/bin:${GOPATH}/bin:${PATH}
fi

3) 编辑器配置

vscode安装

注意配置完vscode编辑器,需要重启

1 默认安装vscode

2 安装插件
	左侧列表按钮图标(扩展) 或者 快捷键Ctrl+Shift+X
	1)语言包 Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code
	2)运行工具 Code Runner
	3)go插件 Go
	4)目录树图标 vscode-icons
3 安装自动提醒插件
	左下角齿轮图标(管理)--命令面板 或者 快捷键Ctrl+Shift+P
	输入Go install
	选择Install/Update Tools
	勾选所有安装
4 首选项:打开用户设置(JSON)
	左下角齿轮图标(管理)--命令面板 或者 快捷键Ctrl+Shift+P
	首选项:打开用户设置(JSON)
vscode用户设置
{
    "editor.renderWhitespace": "all",
    "files.autoSave": "afterDelay",
    "editor.detectIndentation": false,
    "editor.mouseWheelZoom":true,
    "editor.rulers": [
        79,89,99
    ],
    "editor.minimap.enabled": false,
    "files.eol":"\n",
    "files.trimTrailingWhitespace": true,
    "files.trimFinalNewlines": true,
    "workbench.tree.indent": 16,
    "breadcrumbs.enabled": false,
    "editor.suggestSelection": "first",
    "go.formatTool":"goimports",
    "go.useLanguageServer": true,
    "terminal.integrated.defaultProfile.windows": "Command Prompt",
    "go.testFlags": [
        "-count=1",
        "-v"
    ],
    "workbench.iconTheme": "vscode-icons",
}

解释版

{
    "editor.renderWhitespace": "all", 	//空白渲染 空格会显示为 ···
    "files.autoSave": "afterDelay",		//自动保存
    "editor.detectIndentation": false,	//检查缩进:false
    "editor.mouseWheelZoom":true,		//鼠标滚轮变焦true 字体大小
    "editor.rulers": [					//显示行字体数的线
        79,89,99
    ],
    "editor.minimap.enabled": false,	//右侧文本图:不启用
    "files.eol":"\n",					//换行符
    "files.trimTrailingWhitespace": true,	//修改最后空白符
    "files.trimFinalNewlines": true,	//修改换行符
    "workbench.tree.indent": 16,		//工作台树缩进
    "breadcrumbs.enabled": false,		//面包屑 不启用
    "editor.suggestSelection": "first",	//提示建议值:补全建议值
    "go.formatTool":"goimports",		//
    "go.useLanguageServer": true,		//自动下载引入包
    "terminal.integrated.defaultProfile.windows": "Command Prompt",	//默认终端为CMD
    "go.testFlags": [	//单元测试
        "-count=1",		//关闭缓存,默认代码没变化,做测试会使用缓存
        "-v"			//查看测试过程
    ],
    "workbench.iconTheme": "vscode-icons", //使用vscode图标,更清楚展示文件和目录
}

第一个程序 helloworld.go

// helloworld.go
package main 						//声明包名

import "fmt" 						//导入fmt包

func main(){						// 定义main函数
	fmt.Println("Hello World!")		 // 使用fmt包的Println打印
}

// 编译 go build helloworld.go
// 运行 helloworld.exe

go的几个工具

go build

// 展示编译过程 -x
go build helloworld.go
go build -x helloworld.go

// 1 编译生成指定文件 -o
go build -o test.exe helloworld.go

// 2 打印临时目录 --work
go build --work helloworld.go

go run

// 展示执行过程
go run helloworld.go
go run -x helloworld.go

// 3 打印过程不执行 -n
go run -n helloworld.go

查看帮助
	go help 
格式化
	go fmt hellworld.go 

注释

​ 单行注释和多行注释

// helloworld.go
package main //定义包main

import "fmt" //导入fmt包

// 程序入口,main函数
func main(){
	/*
		我是一个注释
		这里调用fmt包的Print函数打印内容到控制台
	*/
	fmt.Println("Hello World!") //打印hello world到控制台
}

变量

作用域

包级别、函数级别、块级别和子块级别

package main

import "fmt"

//包级别
var packageVar string = "pacakge Var"

func main() {
	//函数级别的
	var funcVar string = "func Var"
	{
		//块级别
		var blockVar string = "block Var"
		{
			// 子块级别
			var innerBlockVar string = "inner block var"
			fmt.Println(packageVar, funcVar, blockVar, innerBlockVar)
		}
		fmt.Println(packageVar, funcVar, blockVar)
	}
	fmt.Println(packageVar, funcVar)
}

//打印结果
//D:\GoWork\src\go_course\day01>go run block.go
//pacakge Var func Var block Var inner block var
//pacakge Var func Var block Var
//pacakge Var func Var

父级别不能用子块的变量

package main

import "fmt"

//包级别
var packageVar string = "pacakge Var"

func main() {
	//函数级别的
	var funcVar string = "func Var"
	{
		//块级别
		var blockVar string = "block Var"
		{
			// 子块级别
			var innerBlockVar string = "inner block var"
			fmt.Println(packageVar, funcVar, blockVar, innerBlockVar)
		}
		fmt.Println(packageVar, funcVar, blockVar,innerBlockVar)
	}
	fmt.Println(packageVar, funcVar)

}

/* 打印结果
D:\GoWork\src\go_course\day01>go run block.go
# command-line-arguments
.\block.go:19:45: undefined: innerBlockVar
*/

先找自己,再找父模块的,没找到再向外找

package main

import "fmt"

//包级别
var packageVar string = "pacakge Var"

func main() {
	//函数级别的
	var funcVar string = "func Var"
	var packageVar string = "func package var"
	{
		//块级别
		var packageVar string = "block package var"
		fmt.Println(packageVar)
	}
	fmt.Println(packageVar, funcVar)
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run block.go
block package Var
func package var func Var
*/

作用域总结

1 代码块限定变量使用范围

2 子块可以覆盖父块中定义的变量

声明

四种变量声明
// vars.go
package main

import "fmt"

func main() {
	var name string = "tt" //定义了类型并且初始化了值

	var zeroString string //定义变量类型,但不初始化值
	//初始化使用类型对应的零值(空字符串"")

	var typeString = "tt" //定义变量省略类型,不能省略初始化值
	//通过对应的值类型推导变量的类型

	//短声明(必须在函数内子块使用)
	shortString := "tt"
	//通过对应的值类型推导变量的类型

	fmt.Println(name, zeroString, typeString, shortString)
}

/*
tt  tt tt
*/

多变量声明和单行声明多变量
//var2.go
package main

import "fmt"

var version = "1.0"

func main() {
	/* 	var name string = "tt"
	   	var msg = "hello world"
	   	var desc string */

	var (
		name string = "tt"
		msg         = "hello world"
		desc string
	)

	/* 	x:="x"
	   	y:="y" */
	x, y := "x", "y"
	fmt.Println(name, msg, desc, x, y)
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run vars2.go
tt hello world  x y
*/

赋值

// assign.go
package main

import "fmt"

func main() {
	var name string = "tt"
	fmt.Println(name)

	name = "alice" //更新变量的值(赋值)
	fmt.Println(name)
}

/*打印结果
D:\GoWork\src\go_course\day01>go run assign.go
tt
alice
*/

块内赋值和块内定义
示例1 块内赋值-不是定义
// assign.go
package main

import "fmt"

func main() {
	var name string = "tt"
	fmt.Println(name)

	name = "alice" //更新变量的值(赋值)
	fmt.Println(name)
	{
		//不是定义
		name = "aaaaaaaa"
	}
	fmt.Println(name)
}

/*
D:\GoWork\src\go_course\day01>go run assign.go
tt
alice
aaaaaaaa
*/

示例2 块内定义-外面不更新
// assign.go
package main

import "fmt"

func main() {
	var name string = "tt"
	fmt.Println(name)

	name = "alice" //更新变量的值(赋值)
	fmt.Println(name)
	{
		//不是定义
		// name = "aaaaaaaa"
		var name = "aaaaaaaa"
		fmt.Println(name)
	}
	fmt.Println(name)
}

/*打印结果
D:\GoWork\src\go_course\day01>go run assign.go
tt
alice
aaaaaaaa
alice
*/

基本组成元素

包含(标识符,关键字,字面量,操作符,分隔符)

标识符

// name.go
package main

import "fmt"

func main() {
	/*
	   标识符:程序中定义的名字 变量名,常量名字,函数名字,自定义类型,接口,包名字
	   规范:
	      1. 必须满足:组成只能由非空的Unicode编码字符串、数字、下换线组成
	      2. 必须满足:必须以Unicode编码的字符串或下换线开头(不能以数字开头)
	      3. 必须满足:不能与go的关键字冲突(package,func,var... 25个)
	   建议:
	      1. AsciII编码(a-z,A-Z)/数字、下划线
	      2. 变量使用驼峰式
	         多个英文字母 my_name myName 驼峰
	      3. 与go内置的标识符不要冲突(string...)
	   说明:标识符区分大小写
	      my=""
	      My=""
	*/
	var my = "my"
	var My = "My"
	var 我的名字 = "tt"    // 可以,不建议用
	var _myName = "tt" //可以
	//var 0Name = "tt"   // 不可以
	//var package = "tt" // 不可以
	fmt.Println(my, My, 我的名字, _myName)

}

/* 打印结果
D:\GoWork\src\go_course\day01>go run name.go
my My tt tt
*/

关键字

go语言定义25个关键字

声明:import pacakge 
实体声明和定义: chan cost func interface map struct type var
流程控制: break case continue default defer else fallthrough for go goto
if range return select switch 

操作符和分隔符

算术运算符 + - * / % ++ --
关系运算符 >、 >=、 <、 <=、 ==、 !=
逻辑运算符 &&、 ||、 !
位运算符 &、 |、 ^、 <<、 >>、 &^
赋值运算符 =、 +=、 -=、*=、 /=、 %=、&=、|=、^=、 <<=、 >>=
其他运算符 &(单目)、 *(单目)、 .(点)、 -(单目)、 ...、 <-

小括号() 中括号[] 大括号{} 分号: 逗号,

常量

声明

声明语句用于定义程序的各种实体对象,主要有:
• 声明变量的var
• 声明常量的const
• 声明函数的func
• 声明类型的type

常量声明

//const.go
package main

import "fmt"

const (
	packageName string = "package"
	packageMsg         = "package"
)

func main() {
	const name string = "tt"
	const msg = "msg" //常量可以不使用
	fmt.Println(name)

	// name = "alice" 常量一旦定义不能修改
}

/*打印结果
D:\GoWork\src\go_course\day01>go run const.go
tt
*/

常量和变量不一样

//const2.go
package main

import "fmt"

func main() {
	// const B 不允许
	const (
		A = "test"
		B // 使用前一个常量的值进行初始化(B)
		C // 使用前一个常量的值进行初始化(C=B)
		D = "testD"
		E // 使用前一个常量的值进行初始化(D)
		F // 使用前一个常量的值进行初始化(E=D)
	)
	fmt.Println(B, C)
	fmt.Println(E, F)
}

/*打印结果
D:\GoWork\src\go_course\day01>go run const2.go
test test
testD testD
*/

枚举类型

// enum.go
package main

import "fmt"

func main() {
	const (
		A = iota // 在常量组内使用iota 初始化0 每次调用+1
		B
		C
		D
	)
	fmt.Println(A, B, C, D)
}

/*打印结果
D:\GoWork\src\go_course\day01>go run enum.go
0 1 2 3
*/

// enum.go
package main

import "fmt"

func main() {
	const (
		Mon = iota // 在常量组内使用iota 初始化0, 每次调用+1
		Tue
		Wed
		Thur
		Fir
		Sat
		Sun
	)
	fmt.Println(Mon)
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run enum.go
0
*/

print、println、printf

// print.go
package main

import "fmt"

func main() {
	var name = "tt"
	fmt.Println("*")
	fmt.Println(name) //打印变量加换行
	fmt.Println("*")
	fmt.Print(name) //只打印变量不加换行
	fmt.Println("*")

	fmt.Printf("%T,%v %#v", name, name, name)
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run print.go
*
tt
*
tt*
string,tt "tt"
*/

区分大小写: %t 打印布尔型

总结

1声明 2变量 3作用域 包级别和块级别

数据类型

基本数据类型
	布尔类型	只有两个值 真true 假false
	数值类型
		数字类型 //int uint,int8 uint8(byte),int16 uint16 uintptr 
				//int32(rune) uint32
		浮点类型 //float32 float64 (非精确存储)
		复数类型 
	字符串类型
	指针类型
复合数据类型
	数组
	切片
	map
	自定义类型


布尔类型

声明
// bool.go
package main

import "fmt"

func main() {
	isGirl := false
	fmt.Printf("%T %#v", isGirl, isGirl)
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run bool.go  
bool false
*/

逻辑运算 和 关系运算
//D:\GoWork\src\go_course\day01>go run bool.go
package main

import "fmt"

func main() {
	isGirl := false
	fmt.Printf("%T %#v\n", isGirl, isGirl)

	//操作
	//逻辑运算
	a, b, c, d := true, true, false, false
	// 与: 左操作数与右操作数都为true,结果为true &&
	fmt.Println("a,b:", a && b) // true && true       true
	fmt.Println("a,c:", a && c) // true && false   false
	fmt.Println("c,b:", c && b) // false && true   false
	fmt.Println("c,d:", c && d) // false && false  flase

	// 或: 左操作数与右操作数只要由一个为true,结果为true ||
	fmt.Println("a,b:", a || b) // true || true       true
	fmt.Println("a,c:", a || c) // true || false   true
	fmt.Println("c,b:", c || b) // false || true   true
	fmt.Println("c,d:", c || d) // false || false  flase
	// 非: 取反 true=> false false=>true !
	fmt.Println("a:", !a)
	fmt.Println("c:", !c)

	// 关系运算
	fmt.Println(a == b) // true == true    true
	fmt.Println(a != c) // true != false   true
	fmt.Println(a == c) // true == false   false
	fmt.Println(c != b) // false != true   true
}

零值和占位符%t
// bool.go 
package main

import "fmt"

func main() {
	var bbb bool
	fmt.Println(bbb) //false

	fmt.Printf("%t %t\n", bbb, "bbb")
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run bool2.go
false
false %!t(string=bbb)
*/

数字类型

声明

注意:默认推断为int型

package main

import "fmt"

func main() {
	var age8 int8 = 31
	var age int = 31
	fmt.Printf("%T,%#v,%d\n", age8, age8, age8)
	fmt.Printf("%T,%#v,%d\n", age, age, age)

	fmt.Println(070)
	// fmt.Println(078) //.\int.go:12:16: invalid digit '8' in octal literal
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run int.go
int8,31,31
int,31,31
56
*/

算术运算 和 关系运算

+、 -、 *、 /、 %、 ++、 --

//D:\GoWork\src\go_course\day01>go run int.go
package main

import "fmt"

func main() {
	var age8 int8 = 31
	var age int = 31
	fmt.Printf("%T,%#v,%d\n", age8, age8, age8)
	fmt.Printf("%T,%#v,%d\n", age, age, age)

	fmt.Println(070)
	// fmt.Println(078) //.\int.go:12:16: invalid digit '8' in octal literal

	a, b := 2, 4
	fmt.Println(a + b) //6
	fmt.Println(a - b) //-2
	fmt.Println(a * b) //8
	fmt.Println(a / b) //0
	fmt.Println(a % b) //2

	a++
	b--
	fmt.Println(a, b) //3 3
    
    // 关系运算 > < >= <= != ==
	fmt.Println(a > b)  //false
	fmt.Println(a < b)  //false
	fmt.Println(a >= b) //true
	fmt.Println(a <= b) //true
	fmt.Println(a == b) //true
	fmt.Println(a != b) //false
}


位运算
package main

import "fmt"

func main() {
	/* 	仅了解 位运算
	   	7 => 0111
	   	2 => 0010
	   	按位与 &
	   	按位或 |
	   	取非 ^
		右移位 >>
		左移为 <<
		and not &^
	*/
	fmt.Println(7 & 2)
	fmt.Println(7 | 2)
	fmt.Println(^2)
	fmt.Println(^2)
	fmt.Println(7 >> 2)
	fmt.Println(7 << 2)
	fmt.Println(7 &^ 2) //2取反是-3 相当于7&-3
}

转换后再运算
package main

import "fmt"

func main() {
	var (
		i   int   = 1
		i32 int32 = 1
		i64 int64 = 1
	)
	//类型转换 type(value) int32(i) int(i32) int64(i) int(i64)
	fmt.Println(i + int(i32))
	fmt.Println(i + int(i64))
	fmt.Println(int32(i) + i32)
	fmt.Println(int64(i) + i64)
}

byte rune和占位符%c
package main

import "fmt"

func main() {
	var (
		achar        byte = 'A'
		aint         byte = 65
		unicodePoint rune = '中'
	)
	fmt.Println(achar, aint)
	fmt.Println(unicodePoint)
	fmt.Printf("%d %b %o %x\n", achar, 15, 15, 15)
	fmt.Printf("%U %c\n", unicodePoint, unicodePoint)
	fmt.Printf("%c %c\n", achar, 65)
	fmt.Printf("%#v", unicodePoint)
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run int.go
65 65
20013
65 1111 17 f
U+4E2D 中
A A
20013
*/

浮点数

声明
// float.go
package main

import "fmt"

func main() {
	var height float32 = 1.68
	var heightType = 1.68
	fmt.Printf("%T,%#v,%f\n", height, height, height)
	fmt.Printf("%T,%#v,%f\n", heightType, heightType, heightType)

	var k = 1e3
	fmt.Println(k)
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run float.go
float32,1.68,1.680000
float64,1.68,1.680000
1000
*/

算术运算 和 关系运算
//float.go
package main

import "fmt"

func main() {
	//操作
	//算术运算
	var (
		f1 = 1.2
		f2 = 2.36
	)
	fmt.Println(f1 + f2)
	fmt.Println(f1 - f2)
	fmt.Println(f1 * f2)
	fmt.Println(f1 / f2)

	//不精确
	f1++
	f2--
	fmt.Println(f1, f2)
	fmt.Printf("%f, %f\n", f1, f2)

	//关系运算 如果想要判断== != 判断差值在一定区间范围内
	fmt.Println(f1 > f2)
	fmt.Println(f1 >= f2)
	fmt.Println(f1 < f2)
	fmt.Println(f1 <= f2)
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run float.go
3.5599999999999996
-1.16
2.832
0.5084745762711864
2.2 1.3599999999999999
2.200000, 1.360000
true
true
false
false
*/

赋值运算
package main

import "fmt"

func main() {
	//操作
	//算术运算
	var (
		f1 = 1.2
		f2 = 2.36
	)

	//不精确
	f1++
	f2--
	fmt.Println(f1, f2)
	fmt.Printf("%f, %f\n", f1, f2)

	//关系运算 如果想要判断== != 判断差值在一定区间范围内
	fmt.Println(f1 > f2)
	fmt.Println(f1 >= f2)
	fmt.Println(f1 < f2)
	fmt.Println(f1 <= f2)

	//赋值运算 = += -= /= *=
	f1 = 1.32
	f1 += f2 //f1=f1+f2
	fmt.Println(f1, f2)
}

/*
D:\GoWork\src\go_course\day01>go run float.go
2.68 1.36
*/

decimal解决精度问题
package main

import (
	"fmt"

	"github.com/shopspring/decimal"
)

func main() {
	var (
		a = 1.2
		b = 2.36
	)

	// 加减运算
	c := decimal.NewFromFloat(a)
	d := decimal.NewFromFloat(b)
	fmt.Println(a, b)
	fmt.Println(c, d)
	fmt.Println(a + b)
	fmt.Println(c.Add(d))
    
    // 浮点数乘以100
	fmt.Println(c.Mul(decimal.NewFromInt(100)))

	fmt.Println("**")
	//float64与floay32之间转换
	var aa float32
	aa = 9.99999
	cc := decimal.NewFromFloat32(aa)
	bb := float64(aa)
	fmt.Println(bb)
	fmt.Println(cc.Float64())
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run decimal.go
1.2 2.36
1.2 2.36
3.5599999999999996
3.56
120
**
9.999990463256836
9.99999 false
*/

字符串

声明
//string.go
package main

import "fmt"

func main() {
	var msg = "我的名字\\n是TT"
	var msgRaw = `我的名字\n是TT`
	fmt.Printf("%T %s\n", msg, msg)
	fmt.Printf("%T %s\n", msgRaw, msgRaw)
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run string.go
string 我的名字\n是TT
string 我的名字\n是TT
*/


字符串拼接
//string.go
package main

import "fmt"

func main() {
	var msg = "我的名字\\n是TT"
	var msgRaw = `我的名字\n是TT`
	fmt.Printf("%T %s\n", msg, msg)
	fmt.Printf("%T %s\n", msgRaw, msgRaw)

	//操作
	//字符串连接+
	fmt.Println(msg + msgRaw)
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run string.go
string 我的名字\n是TT
string 我的名字\n是TT
我的名字\n是TT我的名字\n是TT
*/


关系运算
//string.go
package main

import "fmt"

func main() {
	//关系运算 > >= < <= != ==
	//先比较第一个,再比较第二个
	fmt.Println("abc" > "acb") //false
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run string.go
false
*/


赋值运算
//string.go
package main

import "fmt"

func main() {
	var msg = "我的名字\\n是TT"
	//赋值= +=
	msg += "---TT"
	fmt.Println(msg)
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run string.go
我的名字\n是TT---TT
*/

索引 切片 ascii
//string.go
package main

import "fmt"

func main() {
	var msg = "我的名字\\n是TT"
   	var msgRaw = `我的名字\n是TT`
	//索引 切片ascii
	msg = "abcdef"
	fmt.Printf("%T %#v %c\n", msg[0], msg[0], msg[0])
	fmt.Println(msg[1:3])

	//len 字节大小 不是字符数
	fmt.Println(len(msg))
	fmt.Println(len(msgRaw))
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run string.go
uint8 0x61 a
bc
6
19
*/

类型转换 - strconv
package main

import (
	"fmt"
	"strconv"
)

func main() {
	var (
		intVal     = 65
		float64Val = 2.212
		stringVar  = "3.3"
	)

	//整型与浮点型转换
	fmt.Println(intVal, float64Val, stringVar)
	fmt.Printf("%T %#v\n", float64(intVal), float64(intVal))
	fmt.Printf("%T %#v\n", int(float64Val), int(float64Val))

	//字符串与整型
	v, err := strconv.Atoi(stringVar)
	fmt.Println(v, err)

	fmt.Println(string(rune(intVal)))
	fmt.Println(fmt.Sprintf("%#v", intVal))
	fmt.Println(strconv.Itoa(intVal))

	//字符串与浮点型
	vv, err := strconv.ParseFloat(stringVar, 64)
	fmt.Println(vv, err)
	fmt.Println(strconv.FormatFloat(float64Val, 'f', 5, 64))
	fmt.Println(strconv.FormatFloat(float64Val, 'f', 2, 64))
	fmt.Println(strconv.FormatFloat(float64Val, 'g', 5, 64))
	fmt.Println(strconv.FormatFloat(float64Val, 'g', 2, 64))
}

/* 打印结果
D:\GoWork\src\go_course\day01>go run strconv.go
65 2.212 3.3
float64 65
int 2
0 strconv.Atoi: parsing "3.3": invalid syntax
A
65
65
3.3 <nil>
2.21200
2.21
2.212
2.2
*/


指针类型

初始化

加* *int

package main

import "fmt"

func main() {
	//零值
	var (
		pointerInt    *int
		pointerString *string
	)
	fmt.Printf("%T %#v\n", pointerInt, pointerInt)
	fmt.Printf("%T %#v\n", pointerString, pointerString)

	pointerString = new(string)
	fmt.Printf("%#v,%#v\n", pointerString, *pointerString)
}


/*打印结果
D:\GoWork\src\go_course\day01>go run point.go
*int (*int)(nil)
*string (*string)(nil)
(*string)(0xc000044230),""
*/


赋值
package main

import "fmt"

func main() {
	//零值
	var (
		pointerInt    *int
		pointerString *string
	)
	fmt.Printf("%T %#v\n", pointerInt, pointerInt)
	fmt.Printf("%T %#v\n", pointerString, pointerString)

	//赋值
	//使用现有变量 取地址 &name
	age := 32
	fmt.Printf("%T\n", &age)
	pointerInt = &age
	fmt.Println(pointerInt)

	//访问指针对应的值
	//修改指针对应的值
	fmt.Println(*pointerInt)
	*pointerInt = 33
	fmt.Println(age)
}


/*打印结果
D:\GoWork\src\go_course\day01>go run point.go
*int (*int)(nil)
*string (*string)(nil)
*int
0xc0000140e0
32
33
*/

扩展
package main

import (
	"fmt"
)

func main() {
	age := 32
	age2 := age
	fmt.Printf("%T\n", &age)
	pointerInt := &age
	fmt.Println(pointerInt)
	*pointerInt = 33
	fmt.Println(age, age2)
}

/*打印结果
D:\GoWork\src\go_course\day01>go run point2.go
*int
0xc0000140a8
33 32
*/


指针的指针
package main

import "fmt"

func main() {
	//零值 nil
	var (
		pointerInt    *int
		pointerString *string
	)
	fmt.Printf("%T %#v\n", pointerInt, pointerInt)
	fmt.Printf("%T %#v\n", pointerString, pointerString)

	//赋值
	//使用现有变量 取地址 &name
	age := 32
	age2 := age
	fmt.Printf("%T %#v\n", &age, &age)
	fmt.Printf("%T %#v\n", &age2, &age2)
	pointerInt = &age
	fmt.Println(pointerInt)
	fmt.Println(*pointerInt)
	*pointerInt = 3300
	fmt.Printf("%T %p\n", &age, &age)
	age2 = 330000000
	fmt.Printf("%T %p\n", &age2, &age2)

	pointerString = new(string)
	fmt.Printf("%#v,%#v\n", pointerString, *pointerString)
	pp := &pointerString
	fmt.Printf("%T\n", pp)
	**pp = "tt"
	fmt.Println(*pointerString)
	fmt.Println(**pp)
}

/*打印结果
D:\GoWork\src\go_course\day01>go run pointer.go
*int (*int)(nil)
*string (*string)(nil)   
*int (*int)(0xc0000140e0)
*int (*int)(0xc0000140e8)
0xc0000140e0
32
*int 0xc0000140e0        
*int 0xc0000140e8
(*string)(0xc000044230),""
**string
tt
tt
*/

scan
package main

import "fmt"

func main() {
	name := ""
	fmt.Print("请输入你的名字:")
	fmt.Scan(&name)
	fmt.Println("你输入的名字是:", name)

	age := 0
	fmt.Print("请输入你的年龄:")
	fmt.Scan(&age)
	fmt.Println("你输入的年龄是:", age)

	msg := ""
	fmt.Print("请输入你的msg:")
	fmt.Scan(&msg)
	fmt.Println("你输入的msg是:", msg)
}

/*打印结果
D:\GoWork\src\go_course\day01>go run scan.go
请输入你的名字:zt
你输入的名字是: zt
请输入你的年龄:18
你输入的年龄是: 18
请输入你的msg:nihao
你输入的msg是: nihao
*/


输入年龄有误,第一个不能转换为int,会把后边的赋值给下个变量
方式1 用strconv转
方式2 确保输入的为int


package main

import (
	"fmt"
	"strconv"
)

func main() {
	name := ""
	fmt.Print("请输入你的名字:")
	fmt.Scan(&name)
	fmt.Println("你输入的名字是:", name)

	ageStr := ""
	fmt.Print("请输入你的年龄:")
	fmt.Scan(&ageStr)
	age, err := strconv.Atoi(ageStr)
	if err != nil {
		fmt.Println("非法输入")
	} else {
		fmt.Println("你输入的年龄是:", age)
	}

	msg := ""
	fmt.Print("请输入你的msg:")
	fmt.Scan(&msg)
	fmt.Println("你输入的msg是:", msg)
}

/*打印结果
D:\GoWork\src\go_course\day01>go run scan.go
请输入你的名字:zt
你输入的名字是: zt
请输入你的年龄:19
你输入的年龄是: 19
请输入你的msg:23
你输入的msg是: 23
*/

流程控制

if语法

package main

import "fmt"

func main() {
	//买10个包子
	//如果有卖西瓜的,买一个西瓜
	fmt.Println("买10个包子")
	var y string
	fmt.Print("有没有卖西瓜的:")
	fmt.Scan(&y)
	fmt.Println("你输入的是:", y)
	if y == "yes" {
		fmt.Println("买一个西瓜")
	}

}

/*打印结果
D:\GoWork\src\go_course\day01>go run if.go
买10个包子
有没有卖西瓜的:yes
你输入的是: yes
买一个西瓜
*/


ifelse语法

package main

import "fmt"

func main() {
	var y string
	fmt.Print("有没有卖西瓜的:")
	fmt.Scan(&y)
	if y == "yes" || y == "y" {
		fmt.Println("买一个西瓜")
	} else {
		fmt.Println("买10个包子")
	}
}

/*打印结果
D:\GoWork\src\go_course\day01>go run if.go
有没有卖西瓜的:y
买一个西瓜
*/

ifelseif语法

package main

import "fmt"

func main() {
	var score float32
	fmt.Print("请输入分数(0-100):")
	fmt.Scan(&score)
	fmt.Println("你输入的分数是:", score)
	if score >= 90 {
		fmt.Println("A")
	} else if score >= 80 {
		fmt.Println("B")
	} else if score >= 60 {
		fmt.Println("C")
	} else {
		fmt.Println("D")
	}
}

/*打印结果
D:\GoWork\src\go_course\day01>go run ifelseif.go
请输入分数(0-100):32
你输入的分数是: 32
D
*/

switch语法

package main

import (
	"fmt"
)

func main() {
	var y string
	fmt.Print("有没有卖西瓜的:")
	fmt.Scan(&y)
	fmt.Println("你输入的是:", y)
	switch y {
	case "y", "yes", "Y", "Yes", "YES":
		fmt.Println("买一个西瓜")
	case "n", "N", "no", "No", "NO":
		fmt.Println("买10个包子")
	default:
		fmt.Println("输入有误")
	}
}

/*打印结果
D:\GoWork\src\go_course\day01>go run switch.go  
有没有卖西瓜的:y
你输入的是: y
买一个西瓜
*/

package main

import (
	"fmt"
)

func main() {
	var score float32
	fmt.Print("请输入分数:")
	fmt.Scan(&score)
	fmt.Println("你输入的分数是:", score)
	switch {
	case score >= 90:
		fmt.Println("A")
	case score >= 80:
		fmt.Println("B")
	case score >= 60:
		fmt.Println("C")
	default:
		fmt.Println("D")
	}
}

/*打印结果
D:\GoWork\src\go_course\day01>go run switchscore.go
请输入分数:2
你输入的分数是: 2
D
*/

for循环

package main

import "fmt"

func main() {
	//在控制台打印1-10
	for i := 0; i < 10; i++ {
		fmt.Println(i + 1)
	}

	//计算1+2+...+100的和

	total := 0
	for i := 1; i <= 100; i++ {
		total += i
	}
	fmt.Println("total:", total)

	//模拟while循环
	var index = 1
	for index <= 10 {
		fmt.Println(index)
		index++
	}
}

/*打印结果
D:\GoWork\src\go_course\day01>go run for.go
1
2
3
4
5
6
7
8
9
10
total: 5050
1
2
3
4
5
6
7
8
9
10
*/


break

package main

import "fmt"

func main() {
	for index := 1; index < 10; index++ {
		if index == 5 {
			break //循环结束
		}
		fmt.Println(index)
	}
}

/*打印结果
D:\GoWork\src\go_course\day01>go run break.go
1
2
3
4
*/

continue

package main

import "fmt"

func main() {
	for index := 1; index <= 10; index++ {
		if index == 5 {
			continue //跳过本次循环,继续下次循环
		}
		fmt.Println(index)
	}
}

/*打印结果
D:\GoWork\src\go_course\day01>go run continue.go
1
2
3
4
6
7
8
9
10
*/

遍历

package main

import "fmt"

func main() {
	letters := "abcdefghi"
	for i := 0; i < len(letters); i++ {
		fmt.Printf("%c\n", letters[i])
	}

	letters = "我爱中华人民共和国"
	for k, v := range letters {
		fmt.Printf("%T %#v %T %q %c\n", k, k, v, v, v)
	}

}

/*打印结果
D:\GoWork\src\go_course\day01>go run chars.go
a
b
c
d
e
f
g
h
i
int 0 int32 '我' 我
int 3 int32 '爱' 爱
int 6 int32 '中' 中
int 9 int32 '华' 华
int 12 int32 '人' 人
int 15 int32 '民' 民
int 18 int32 '共' 共
int 21 int32 '和' 和
int 24 int32 '国' 国
*/

死循环loop

package main

import "fmt"

func main() {
	var (
		index = 0
		total = 0
	)
	for {
		total += index
		index++
		if index > 100 {
			break
		}
	}
	fmt.Println(total)
}

/*打印结果
D:\GoWork\src\go_course\day01>go run loop.go
5050
*/

作业

1. 打印乘法口诀
   1 * 1 = 1
   2 * 1 = 2   2 * 2 = 4
   3 * 1 = 3   3 * 2 = 6   3 * 3 = 9
   ...
   9 * 1 = 9 ...                          ...  9 * 9 = 81

2. 猜数字游戏
   生成随机整数[0, 100)
   提示用户再控制台输入猜测的数字
   比较,当用户输入较大,提示太大了
       当用户输入太小,提示太小了
       当用户输入正确,提示经过N次对了,太聪明了
   用户最多猜5次,如果5次内都没有猜正确,提示太笨了,游戏结束

3. 扩展: 当成功或失败后,提示用户是否继续,输入:yes, y, Y则继续,重新生成随机数,让用户猜测

1 打印乘法口诀

要求:对齐
提示代码