Go (一) 基础部分1 -- 基础语法,数据结构,常量,变量,运算符

一、安装Go 

1.1、mac 上安装go

官网:https://golang.org/dl/

mac下载地址:https://golang.org/dl/go1.15.5.darwin-amd64.pkg

mac版下载完毕后直接安装。默认放在 /usr/local/go/ 目录下 (重开iterm窗口即可默认生效。)

1.2、win上安装go

官网:https://golang.org/dl/

地址:https://go.dev/dl/go1.21.1.windows-amd64.msi

安装路径放在"D:\Go"

二、配置GOROOT

2.1、mac使用默认路径 /usr/local/go 路径即可

2.2、mac使用默认路径"D:\Go"路径即可

三、配置GOPATH(GOPATH是一个环境变量)

WIN默认路径是:"C:\Users\xxx\go"

在用户环境变量中,修改GOPATH路径为:"E:\Goland_Document"

在"E:\Goland_Document"目录下依次新建目录"bin pkg src"三个目录

在用户环境变量Path中,新增:"E:\Goland_Document\bin"

MAC默认路径是:/Users/xxxxxx/go  当前的用户家目录下的go目录。

3.1、自定义修改

可使用 go env 命令查看当前go相关的环境变量

可编辑 ~/.bash_profile 目录设置 GOPATH 的路径。

export GOPATH=/Users/xxxxx/Desktop/Go/GoPath/go

生效:source  ~/.bash_profile

不过这种方式只是临时生效。

3.2、使用默认的目录

在默认的 /Users/xxxxxx/go 目录下一次创建:bin,pkg,src 目录

3.3、查看go的环境变量相关信息,使用:go env

3.4、开发结构,一般用域名来区分不同的包

四、GO的编译

4.1、go build    # 编译成可执行文件

将当前目录下的go代码文件编译为二进制文件(编译后的可执行文件名,为当前文件所在父目录)

编译后的可执行文件,直接执行:

4.2、go build -o "test.exe"    # 编译后的文件重命名

将编译的可执行文件重命名为 "test.exe"

4.3、go run "main.go"    # 运行xx.go文件

运行go代码文件

报错:

如果go env里面的"set GOOS=linux"时,那么执行go run "main.go" 会报错:

exec: "C:\\Users\\xxx\\AppData\\Local\\Temp\\go-build2764083230\\b001\\exe\\main": file does

此时需要将GOOS=linux,更改为GOOS=windows

执行命令 go env -w GOOS=windows

然后重新执行go run "main.go"即可

4.4、go install 

分为2个步骤

1.先编译得到一个可执行文件,

2.将可执行文件移动到 GOPATH/bin 目录下。

4.5、编译 linux 和 windows 平台64位可执行程序

编译后的可执行文件在linux服务器上运行

SET CGO_ENABLED=0

SET GOOS=linux

SET GOARCH=amd64

go build

编译后的可执行文件在windows服务器上运行
SET
CGO_ENABLED=0

SET GOOS=windows

SET GOARCH=amd64

go build

五、GO的基础语法

5.1、注释

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

5.2、go代码

// 当前程序的包名
package main

//导入包
import "fmt"
//函数外只能放置标识符(变量|常量|函数|类型)的声明

//同时导入多个包:
import (
    "fmt"
    "math"
)

//程序的入口
func main()  {
	fmt.Println("Test")
}

5.2.1、代码关键字说明

package main

    package是一个关键字,用来声明文件属于哪个"包",main是"包名"。(在go中,每个文件都必须归属一个"包")

    同时main表示当前文件被编译后是一个可执行的文件

    同时代码还需要一个函数func main(){}作为入口

import "fmt"

    引入一个"包",使用该"包"的功能。

func main(){}

    func是关键字,表示main是一个函数,"main"是函数名称,是一个主函数,是当前程序的入口。

5.3、关键字

通过 const 关键字来进行常量的定义。
通过在函数体外部使用 var 关键字来进行全局变量的声明和赋值。
通过 type 关键字来进行结构(struct)和接口(interface)的声明。
通过 func 关键字来进行函数的声明。

六、变量和常量

6.1、变量:Go 语言变量名字母、数字、下划线组成,其中首个字符不能为数字。

1、变量的命名方式:var 变量名 变量类型

2、变量类型:常见变量的数据类型有:整数型、浮点型、布尔型等(Go语言中的每一个变量都有自己的类型)

3、变量声明:变量必须经过声明才能开始使用,并且Go语言的变量声明后必须使用

变量声明以关键字var开头,变量类型放在变量的后面,行尾无需分号。例子:
    var name string
    var age int
    var isOk bool

批量变量声明
    var (
        aaa string
        bbb int
        ccc bool
        ddd float32

    )

4、变量赋值(方式1)
Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值

例如: 整型和浮点型变量的默认值为0。 字符串变量的默认值为空字符串。 布尔型变量默认为false。 切片、函数、指针变量的默认为nil。

变量赋值格式var 变量名 变量类型 = 表达式

举个例子:
    var name string = "Q1mi"
    var age int = 18

5、变量类型推导(简化变量赋值)(方式2)
有时候我们会将变量的类型省略,这个时候编译器会根据等号右边的值来推导变量的类型完成初始化。

    例子:
    var name = "Q1mi"
    var age = 18

    一次对多个变量同时赋值(方法1)
    var name, age = "sudada", 20

    一次对多个变量同时赋值(方法2)

    var (

        name = "sudada"

        age = 20

    )

6、短变量声明(:=)只能在函数内部使用(方式3,函数内使用)
在函数内部,可以使用更简略的 " := " 方式声明并初始化变量。

    例子:
    name := "Q1mi"
    age := 18

    一次对多个变量同时赋值
    name, age := "sudada", 2

7、匿名变量
在使用多重赋值时,如果想要忽略某个值,可以使用匿名变量(anonymous variable)。 匿名变量用一个下划线_表示,例如:

func foo() (int, string) {
    return 10, "Q1mi"
}
func main() {
    x, _ := foo()
    _, y := foo()
    fmt.Println("x=", x)
    fmt.Println("y=", y)
}

匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。 (在Lua等编程语言里,匿名变量也被叫做哑元变量。)

注意事项:
函数外的每个语句都必须以关键字开始(var、const、func等)
:=  不能使用在函数外。
_   多用于占位,表示忽略值。

package main

import "fmt"

var name = "sudada"
var age = 18
var isOk = false

//变量声明后必须使用
func main() {
	name = "理想"
	age = 18
	isOk = true
	fmt.Println(isOk)           //直接打印输出,无换行符
	fmt.Println(age)            //直接打印输出,有换行符
	fmt.Printf("name:%s", name) // %s:占位符  使用name这个变量的值去替换占位符,无换行符
	fmt.Println()

	//短变量声明,只能在函数内使用,不能在全局使用
	A := "aa"
	B := "bb"
	fmt.Println(A)
	fmt.Println(B)
}

6.2、常量

常量是一个简单值的标识符,在程序运行时,不会被修改的量,

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

1、变量的命名方式:const 变量名 变量类型 =常量的值

2、相对于变量,常量是恒定不变的值,常量在定义的时候必须赋值
const pi float64 = 3.14
const e int = 111

3、声明了pi和e这两个常量并赋值之后,在程序运行期间常量的值不能再修改了
多个常量也可以一起声明:
const (
    pi = 3.14
    e = 111
)

4、const同时声明多个常量时,如果省略了值则表示和上面一行的值相同。 例如:
const (
    n1 = 100
    n2
    n3
)

5、常量只能修饰bool,数值类型(int,float系列),string类型
上面示例中,常量n1、n2、n3的值都是100。

package main

import "fmt"

const pi = 11.111

const (
	status   = 200
	notfound = 404
)

const (
	n1 = 100
	n2
	n3
)

func main() {
	fmt.Println(pi)
	fmt.Println(status)
	fmt.Println(notfound)

	fmt.Println(n1)
	fmt.Println(n2)
	fmt.Println(n3)
}

6.3、iota  ( iota是go语言的常量计数器,只能在常量的表达式中使用 )

1、iota在const关键字出现时将被重置为0const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。 使用iota能简化定义,在定义枚举时很有用。举个例子:
const (
        n1 = iota //0
        n2        //1
        n3        //2
        n4        //3
    )

2、几个常见的iota示例:使用_跳过某些值
const (
        n1 = iota //0
        n2        //1
        _
        n4        //3
    )

3、iota声明中间插队
const (
        n1 = iota //0
        n2 = 100  //100
        n3 = iota //2
        n4        //3
    )
const n5 = iota //0

package main

import "fmt"

const (
	a1 = iota //0
	a2        //1
	a3        //2
)

const (
	b1 = iota //0
	b2        //1
	_
	b4 //3
)

const (
	c1 = iota //0
	c2 = 100  //100
	c3 = iota //2
	c4        //3
)

const n5 = iota //0

func main() {
	fmt.Println("a3:", a3)
	fmt.Println(a2)
	fmt.Println(a3)
	fmt.Println("b4:", b4)
	fmt.Println("c4:", c4)
}

4、iota 的使用例子

  1)、iota 单行使用时,计数测试(单行计数+1次)

package main

import "fmt"

const (
	d1 = iota + 1  // 0+1=1
	d2 = iota + 2  // 1+2=3
	d3 = iota + 1  // 2+1=3
	d4 = iota + 2  // 3+2=5
)

func main() {
	fmt.Println("d1: ", d1)
	fmt.Println("d2: ", d2)
	fmt.Println("d3: ", d3)
	fmt.Println("d4: ", d4)
}

//d1:  1
//d2:  3
//d3:  3
//d4:  5

  2)、iota 一行有2个iota时,计数测试(单行计数+1次)

package main

import "fmt"

const (
	szq1, szq2 = iota + 1, iota + 2  // 0+1=1, 0+2=2
	szq3, szq4 = iota + 1, iota + 2  // 1+1=2, 1+2=3
)

func main() {
	fmt.Println("szq1: ", szq1)
	fmt.Println("szq2: ", szq2)
	fmt.Println("szq3: ", szq3)
	fmt.Println("szq4: ", szq4)
}

//szq1:  1
//szq2:  2
//szq3:  2
//szq4:  3

3)iota 只是在同一个 const 常量组内递增,每当有新的 const 关键字时,iota 计数会重新开始。

package main

const (
	i = iota
	j = iota
	x = iota
)
const xx = iota
const yy = iota

func main() {
	println(i, j, x, xx, yy)
}
// 输出是 0 1 2 0 0

 七、GO的基本数据类型(Golang程序在定义变量时,经量使用占用空间小的数据类型)

7.1、Go 语言按类别有以下几种基本数据类型:

序号类型和描述
1布尔型 bool
布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。默认值为 false
2

数字类型
整数型 int32 int64 默认值为 0

浮点型 float32、float64(默认使用)  默认值为 0

Go 语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码

3字符串类型 string
字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本。默认值为 "空"
序号类型和描述
1byte(一般接收单个字符串的场景使用),详见12.1例子2
类似 uint8(有符号 8 位整型 (-128 到 127))
2rune(一般接收单个字符串的场景使用),详见12.1例子2
类似 int32(有符号 32 位整型 (-2147483648 到 2147483647))
序号类型和描述
1uint8
无符号 8 位整型 (0 到 255)
2uint16
无符号 16 位整型 (0 到 65535)
3uint32
无符号 32 位整型 (0 到 4294967295)
4uint64
无符号 64 位整型 (0 到 18446744073709551615)
5int8
有符号 8 位整型 (-128 到 127)
6int16
有符号 16 位整型 (-32768 到 32767)
7int32(一般接收单个字符串的场景使用),详见12.1例子2
有符号 32 位整型 (-2147483648 到 2147483647)
8int64
有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)

7.2、格式化

    %T:查看数据类型
    %b:二进制数

    %o:八进制数

    %d:十进制数
    %x:十六进制数
    %c:字符
    %s:字符串
    %p:指针
    %v:值
    %f:浮点数

常用的有:

    %T   查看数据类型 (例子:fmt.Printf("%T",num) 查看变量num的数据类型 )
    %v   查看变量的值(value),万能用法
    %s   字符串类型的变量去替代
    %d   整数类型的变量去替代
    %t    bool类型的变量去替代

    unsafe.Sizeof(变量名)  变量占用的字节大小

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	num := 3
	fmt.Printf("%T \n",num) // 查看变量num的数据类型,返回值:int
	fmt.Printf("%v \n",num) // 返回值:3
	fmt.Printf("%d \n",num) // 返回值:3
	fmt.Println(unsafe.Sizeof(num)) // 查看变量num占用的"字节大小",返回值:8

	name := "sudada"
	fmt.Printf("%T \n",name) // 查看变量name的数据类型,返回值:string
	fmt.Printf("%v \n",name) // 返回值:sudada
	fmt.Printf("%s \n",name) // 返回值:sudada
	fmt.Println(unsafe.Sizeof(name)) // 查看变量name占用的"字节大小",返回值:16

}

7.3、指针类型(变量的内存地址)

& 取出变量的内存地址

* 根据内存地址取出对应的值

func main() {
	var str string = "sudada"
	var num int = 10

	// 获取变量的指针地址,使用 &
	fmt.Println(&str)  // 返回值:0xc000024070
	fmt.Println(&num)    // 返回值:0xc00000a0e8

	// 变量类型为"指针类型": *int
	// 变量ptr的值是变量"num"指针地址: &num
	var ptr *int = &num
	fmt.Println(ptr)    // 返回值:0xc00000a0e8

	// 获取指针变量的值,使用 *
	fmt.Println(*ptr)    // 返回值:10
}

例子1:将"变量的内存地址对应的值"修改后,"变量的值"就等于修改后的值

func main() {
	var num int = 10
	fmt.Println(num)  // 返回值:10

	// 变量ptr的值就是变量num的指针地址
	var ptr *int = &num
	// *ptr 拿到num的内存地址的值10,并给num重新赋值为11
	*ptr = 11
	// 此时num的值为11
	fmt.Println(num)  // 返回值:11
    fmt.Println(*ptr)  // 返回值:11
}

例子2:将"变量的内存地址对应的值"修改后,"变量的值"就等于修改后的值

func main() {
	var a int = 300
	var b int = 400
	var ptr1 *int = &a  // 给变量ptr1赋值为a的内存地址
	*ptr1 = 100  // 此时a = 100

	ptr1 = &b  // 给变量ptr1重新赋值为b的内存地址
	*ptr1 = 200  // 此时b = 200
	fmt.Printf("%v %v \n",a,b)  // 返回值:100 200
}

7.4、值类型和引用类型

1)值类型int,float,bool,string,数组,结构体struct

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

2)引用类型指针,slice切片,map,管道chanel,接口interface

变量存储是一个内存地址,这个地址对应的空间是真正存储数据的值,内存通常在堆上分配,当没有任何变量引用这个地址时,那么这个内存地址会被垃圾回收。

八、字符串

8.1、字符串

Go 语言里的字符串的内部实现使用UTF-8编码。 字符串的值为 双引号"" 中的内容
例如:
s1 := "hello"
s2 := "你好"

8.2、字符()
写法:'xxx' ,其中xxx是字符内容,单独的字母汉字符号 都表示一个字符。
例如:
a1 := 'a'
b1 := '1'
c1 := '苏'

8.3、字符串转义符
Go 语言的字符串常见转义符包含回车、换行、单双引号、制表符等,如下表所示。

转义符含义
\r回车符(返回行首)例子:fmt.Println("abc\rdef"),打印的是"def","回车"会把"abc"覆盖掉
\n换行符(直接跳到下一行的同列位置)
\t制表符,一个tab,实现代码对其的功能
\'单引号
\"双引号
\\反斜杠

举个例子,我们要打印一个Windows平台下的一个文件路径:

package main
import (
    "fmt"
)
func main() {
    fmt.Println("str := \"c:\\Code\\lesson1\\go.exe\"")
}

// str := "c:\Code\lesson1\go.exe"

8.4、多行字符串
Go语言中要定义一个多行字符串时,就必须使用 反引号`` 字符(反引号内的内容原样输出):

func main() {
    s1 := `第一行
第二行
第三行
`
    fmt.Println(s1)
}
//第一行
//第二行
//第三行

8.5、字符串的常用操作

方法介绍
len(str)字符串长度
+ 或 fmt.Sprintf拼接字符串
strings.Split分割
strings.contains判断是否包含
strings.HasPrefix,strings.HasSuffix前缀/后缀判断
strings.Index(),strings.LastIndex()子串出现的位置
strings.Join(a[]string, sep string)join操作
func main() {
	// 字符串相关操作len()
	s1 := `sudada`
	fmt.Println(len(s1)) // 6

	// 字符串拼接
	name := "lixiang"
	world := "dsb"
	test1 := name + world // 字符串直接拼接
	fmt.Println(test1)    // lixiangdsb

	test2 := fmt.Sprintf("%s%s", name, world) // 字符串拼接完毕后作为一个返回值
	fmt.Println(test2)    // lixiangdsb

	// 字符串分割,使用 strings.Split("要分割的对象", "分隔符")
	sudada := "c:\\Code\\lesson1\\go.exe\\"
	szq := strings.Split(sudada, "\\")
	fmt.Println(szq) // [c: Code lesson1 go.exe ]

	// 判断一个值,是否被包含,返回 true | false
	fmt.Println(strings.Contains(sudada, "go")) // true

	// 拼接 join:把字符串做拼接
	fmt.Println(strings.Join(szq, "+"))
	// 拼接前:[c: Code lesson1 go.exe ] 
	// 拼接后:c:+Code+lesson1+go.exe+
}

8.6、字符串去除空格和换行符

func main() {
	str := "这里是 www\n.runoob\n.com"
	fmt.Println("-------- 原字符串 ----------")
	fmt.Println(str)
	// 去除空格
	str = strings.Replace(str, " ", "", -1)
	// 去除换行符
	str = strings.Replace(str, "\n", "", -1)
	fmt.Println("-------- 去除空格与换行后 ----------")
	fmt.Println(str)
}

九、基本数据类型的转换

9.1、int类型转float类型

func main() {

	// int类型转float类型
	var a int = 100
	var b = float64(a)
	fmt.Printf("%v %T \n",a,a)  // 返回值:100 int
	fmt.Printf("%v %T \n",b,b)  // 返回值:100 float64
}

9.2、基本数据类型(int bool float) 转换为 string类型

import (
	"fmt"
	"strconv"
)

func main() {
	var num1 int64 = 100
	var float1 float64 = 10.123
	var b bool = false
	var str string

	// int类型转string类型
	//方式1,使用"fmt.Sprintf"方法
	str = fmt.Sprintf("%d", num1)
	fmt.Printf("%v %T \n",str,str)	// 返回值:100 string

	// float类型转string类型
	str = fmt.Sprintf("%f", float1)
	fmt.Printf("%v %T \n",str,str)	// 返回值:10.123000 string

	// bool类型转string类型
	str = fmt.Sprintf("%t", b)
	fmt.Printf("%v %T \n",str,str)	// 返回值:false string

	// int类型转string类型
	//方式2,使用"strconv"方函数
	str = strconv.FormatInt(num1,10)   // 10表示10进制
	fmt.Printf("%v %T \n",str,str)	// 返回值:100 string

	// float类型转string类型
	str = strconv.FormatFloat(float1,'f',10,64)  // f 格式,10表示保留10位小数,64表示float64
	fmt.Printf("%v %T \n",str,str)	// 返回值:10.1230000000 string

	// bool类型转string类型
	str = strconv.FormatBool(b)
	fmt.Printf("%v %T \n",str,str)	// 返回值:false string
}

9.3、string类型 转换为 基本数据类型(int bool float)

import (
	"fmt"
	"strconv"
)

func main() {
	var str1 string = "true"
	var b bool
	// string类型转bool类型
	b,_ = strconv.ParseBool(str1) // 函数返回了2个值(value bool, err error)
	fmt.Printf("%T %v \n",b,b)  // 返回值:bool true

	var str2 string = "100"
	var i int64
	// string类型转int类型
	i,_ = strconv.ParseInt(str2,10, 64)
	fmt.Printf("%T %v \n",i,i)  // 返回值:int64 100

	// string类型转float类型
	var str3 string = "10.123"
	var f float64
	f,_ = strconv.ParseFloat(str3,64)
	fmt.Printf("%T %v \n",f,f)  // 返回值:float64 10.123
}

注意事项:string在转换为基本数据类型时,确保string类型能够转换为有效的数据。

十、运算符

10.1、算术运算符

注意:

++(自增)和 --(自减)在Go语言中是单独的语句,并不是运算符

++ 和 -- 只能写在变量的后面,即:a++ 或 a-- 不能写成:++a 或 --a

案例

func main() {
	// ++ 和 -- 的使用
	var i int = 10
	i++
	fmt.Println(i)  // 返回值:10 + 1 = 11
	i--
	fmt.Println(i)  // 返回值:11 - 1 = 10

    // 变量赋值
	var num int = 10
	num++
	a := num // 不能写成:a := num++
	fmt.Println(a) // 返回值:11

	num--
	b := num // 不能写成:a := num--
	fmt.Println(b) // 返回值:10
}
运算符描述
+相加
-相减
*相乘
/相除
%取余

案例

func main() {
	// 除法运算:整数和整数做除法运算时,会把得到的结果去掉小数部分,只保留整数部分。
	fmt.Println(10/4)   // 10除4等于2.5,去掉小数0.5,那么返回值为:2
	// 怎么保留小数部分,需要有浮点数参与运算
	fmt.Println(10.0/4)  // 返回值:2.5
	fmt.Println(10/4.0)  // 返回值:2.5

	// 取余运算
	// 公式:a * b = a - (a / b * b)
	fmt.Println(10%3)  // 返回值:1
	fmt.Println(-10%3)  // 返回值:-1
	fmt.Println(10%-3)  // 返回值:1
	fmt.Println(-10%-3)  // 返回值:-1
}

10.2、关系运算符

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

10.3、逻辑运算符

    A = True    B=Flase

运算符描述
&&逻辑 AND 运算符。 如果两边的操作数都是 True,则为 True,否则为 False。例子:(A && B),返回值为False
||逻辑 OR 运算符。 如果两边的操作数有一个 True,则为 True,否则为 False。例子:(A || B),返回值为True
!逻辑 NOT 运算符。 如果条件为 True,则为 False,否则为 True。例子:!(A && B),返回值为True

二进制:0,1,满2进1

十进制:0-9,满10进1

八进制:0-7,满8进1,以数字0开头表示

十六进制:0-9及A-F,满16进1,以0x或0X开头,A-F不区分大小写。

二进制转十进制:

        从最低位开始(右边),将每个位上的数提取出来,乘以2的(位数-1)次方,然后求和

        案例:二进制 1011 转为十进制的数字

        1011 = 1 * 2(0次方=1) + 1 * 2(1次方=2) + 0 * 2(2次方=4) + 1 * 2(3次方=8) = 1 + 2 + 0 + 8 = 11

八进制转十进制:

        从最低位开始(右边),将每个位上的数提取出来,乘以8的(位数-1)次方,然后求和

        案例:八进制 0123 转为十进制的数字

        0123 = 3 * 8(0次方=1) + 2 * 8(1次方=8) + 1 * 8(2次方=64) + 0 * 8(3次方=0) = 3 + 16 + 64 + 0 = 83

十六进制转十进制:

        从最低位开始,将每个位上的数提取出来,乘以16的(位数-1)次方,然后求和

        案例:十六进制 0x34A 转为十进制的数字

        0x34A = 10 * 16(0次方=1) + 4 * 16(1次方=16) + 3 * 16(2次方=256) = 10 + 64 + 768 = 842

十进制转二进制:

        将该数不断除以2,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制

        案例:十进制 56 转为二进制

        56 = 111000

十进制转八进制:

        将该数不断除以8,直到商为0为止,然后将每步得到的余数倒过来,就是对应的八进制

        案例:十进制 156 转为八进制

        156 = 0234

十进制转十六进制:

        将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的十六进制

        案例:十进制 356 转为十六进制

        356 = 164

二进制转八进制:

        将二进制数每三位一组(从低位开始组合),转成对应的八进制数即可。

        案例:二进制 11010101 转为八进制

        11010101 = 325

二进制转十六进制:

        将二进制数每四位一组(从低位开始组合),转成对应的十六进制数即可。

        案例:二进制 11010101 转为十六进制

        11010101 = 0xD5

八进制转二进制:

        将八进制数每1位,转成对应的一个3位的二进制数即可。

        案例:八进制 0237 转为二进制

        0237 = 10011111

十六进制转二进制:

        将十六进制数每1位,转成对应的一个4位的二进制数即可。

        案例:十六进制 0x237 转为二进制

        0x0237 = 1000110111

10.4、位运算符

位运算符对整数在内存中的二进制位进行操作。

运算符描述
&参与运算的两数各对应的二进位相与。
(两位均为1才为1,否则为0)
|参与运算的两数各对应的二进位相或。
(两位有一个为1就为1,两位都不为1则为0)
^参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。
(两位不一样则为1,两位一样则为0)
<<左移n位就是乘以2的n次方。
“a<<b”是把a的各二进位全部左移b位,高位丢弃,低位补0。
>>右移n位就是除以2的n次方。
“a>>b”是把a的各二进位全部右移b位。

10.5、赋值运算符

运算符描述
=简单的赋值运算符,将一个表达式的值赋给一个左值。例子:C=A+B
+=相加后再赋值。例子:C+=A 等于 C=C+A
-=相减后再赋值。例子:C-=A 等于 C=C-A
*=相乘后再赋值。例子:C*=A 等于 C=C*A
/=相除后再赋值。例子:C/=A 等于 C=C/A
%=求余后再赋值。例子:C%=A 等于 C=C%A
<<=左移后赋值。例子:C<<=2 等于 C=C<<2
>>=右移后赋值。例子:C>>=2 等于 C=C>>2
&=按位与后赋值。例子:C&=2 等于 C=C&2
|=按位或后赋值。例子:C|=2 等于 C=C|2
^=按位异或后赋值。例子:C^=2 等于 C=C^2
例子
func main() {
	var num1 int = 10
	var num2 int = 20
	num1 += num2
	fmt.Println(num1)  // 返回值:30

	// 在不使用中间变量的方式,实现a,b两个变量的值相关转换,即a=200,b=100
	var a int = 100
	var b int = 200
	fmt.Println(a)  // 返回值:100
	fmt.Println(b)  // 返回值:200

	a = a+b // a=a+b
	b = a-b // a-b == (a+b)-b=a,此时b=a
	a = a-b // a-b == (a+b)-a=b,此时a=b
	fmt.Println(a)  // 返回值:200
	fmt.Println(b)  // 返回值:100
}

十一、fmt 标准库

11.1、获取用户输入的值:

1、fmt.Scan 从标准输入中扫描用户输入的数据,将以空白符分隔的数据分别存入指定的参数。

// fmt.Scan从标准输入中扫描用户输入的数据,将以空白符分隔的数据分别存入指定的参数。
func main() {
	var (
		name string
		age int
		married bool
	)
	fmt.Scan(&name, &age, &married)
	fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
}

//手动输入:szq
//手动输入:18
//手动输入:true
//返回结果:扫描结果 name:szq age:18 married:true

2、fmt.Scanln 遇到回车键就结束扫描了,这个比较常用

// fmt.Scanln 遇到回车就结束扫描了,这个比较常用。
func main() {
	var (
		name string
		age int
		married bool
	)
	fmt.Scanln(&name, &age, &married)
	fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
}

//手动输入:szq 18 true (空格作为分隔符)
//返回结果:扫描结果 name:szq age:18 married:true

3、fmt.Scanf  不同于fmt.Scan简单的以空格作为输入数据的分隔符,fmt.Scanf为输入数据指定了具体的输入内容格式,只有按照格式输入数据才会被扫描并存入对应变量。

// fmt.Scanf 不同于fmt.Scan简单的以空格作为输入数据的分隔符,fmt.Scanf为输入数据指定了具体的输入内容格式,只有按照格式输入数据才会被扫描并存入对应变量。
func main() {
	var (
		name string
		age int
		married bool
	)
	fmt.Scanf("%s %d %t", &name, &age, &married)
	fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
}

11.2、通用占位符

占位符说明
%v值的默认格式表示
%+v类似%v,但输出结构体时会添加字段名
%#v值的Go语法表示
%T打印值的类型
%%百分号
func main() {
	fmt.Printf("%v\n", 100)   // 100
	fmt.Printf("%v\n", false) // false
	o := struct{ name string }{"小王子"}
	fmt.Printf("%v\n", o)  // {小王子}
	fmt.Printf("%#v\n", o) //struct { name string }{name:"小王子"}
	fmt.Printf("%T\n", o)  //struct { name string }
	fmt.Printf("100%%\n")  //100%
}

十二、标识符的命名规范

12.1、系统保留关键字

12.2、标识符命名

包名:尽量将package的名称目录名称保持一致,包名不要和标准库的包名冲突。

变量名,函数名,常量名首字母大写,则可以被其他的包访问首字母小写,则只能在本包中使用

// main.go 文件
package main
import (
	"Study/go002/module"
	"fmt"
)
func main() {
	fmt.Println(module.MyName)  // 返回值 "sudada"
}

// module.go 文件
package module
var MyName string = "sudada"

十二、引号

12.1、单引号 ''  (单个字符,使用单引号)

单引号表示 rune(int32) 类型,单引号里面是单个字符单引号里面不能写多个字符单个字符对应的值为该字符的 ASCII 值。

func main() {
	a1 := 'a'
	b1 := '1'
	c1 := '苏'
	fmt.Println(a1)  // 返回值:97
	fmt.Println(b1)  // 返回值:49
	fmt.Println(c1)  // 返回值:33487
	fmt.Printf("%T\n",a1)  // 返回值:int32
	fmt.Printf("%T\n",b1)  // 返回值:int32
	fmt.Printf("%T\n",c1)  // 返回值:int32
}

例子2:接收单个字符串时

func main() {
	var str1 int32
	str1 = '1'
	fmt.Println(str1) // 返回值:45
	fmt.Printf("%T\n",str1) // 返回值:int32

	var str2 rune
	str2 = '-'
	fmt.Println(str2) // 返回值:97
	fmt.Printf("%T\n",str2) // 返回值:int32

	var str3 byte
	str3 = 'a'
	fmt.Println(str3) // 返回值:42
	fmt.Printf("%T\n",str3) // 返回值:uint8
}

12.2、双引号 ""   (多个字符,使用双引号)

单引号表示string类型

func main() {
	a1 := "A"
	b1 := "1"
	c1 := "王"
	fmt.Println(a1)  // 返回值:A
	fmt.Println(b1)  // 返回值:1
	fmt.Println(c1)  // 返回值:王
	fmt.Printf("%T\n",a1)  // 返回值:string
	fmt.Printf("%T\n",b1)  // 返回值:string
	fmt.Printf("%T\n",c1)  // 返回值:string
}

12.3、反引号``

func main() {
	a := `Hello World
xxx
xxx`
	fmt.Println(a)
}

// Hello World
// xxx
// xxx

十三、go mod 说明

下载包go get github.com/gin-gonic/gin
  下载最新版本包:go get -u github.com/gin-gonic/gin
  下载指定版本包:go get github.com/example/package@latest

步骤1(初始化 Go Modules):go mod init your_module_name,这将创建一个 go.mod 文件,记录你的项目的模块信息和当前依赖关系;
步骤2(复制依赖包到vendor目录):"go mod vendor" 会将项目的所有包复制到vendor目录中。这包括go.mod文件中声明的依赖包;
步骤3(go mod download:会根据当前项目的go.mod文件,下载并安装所有依赖包;

13.1、go.mod文件说明(Go项目模块的配置文件,用于管理项目的依赖关系和版本信息)
1.模块声明:
每个Go模块的go.mod文件的第一行通常包含模块声明,指定模块的路径和版本。例如:module example.com/myproject
2.依赖声明:在go.mod文件中,你会看到列出了项目依赖的其他模块以及它们的版本信息。例如:require (github.com/gin-gonic/gin v1.7.4),这表示项目依赖于 github.com/gin-gonic/gin 模块的版本 v1.7.4。
3.更新模块版本:你可以使用 go get 命令来更新模块的版本。例如:go get github.com/gin-gonic/gin@latest,这会将 github.com/gin-gonic/gin 模块更新到最新版本。
4.go.mod文件:是"Go Modules"的核心,它使得Go项目的依赖管理更加灵活和精确。在创建新的Go项目时,"Go Modules"会自动生成go.mod文件,而在使用其他人的项目时,你可以使用 go get 等命令来处理依赖关系。

13.2、"go mod download"命令说明:(会根据当前项目的go.mod文件,下载并安装所有依赖包)
1.指定版本下载
:如果go.mod文件中指定了特定的依赖版本,"go mod download" 将下载这些指定版本的依赖项。这确保了项目在不同环境中使用相同的依赖版本。
2.更新go.sum文件:与"go get 不同,"go mod download" 不会更改go.mod文件中的版本信息,但会更新go.sum文件。这是因为"go mod download"主要用于下载依赖项,而不是更新它们的版本。
3.并发下载:"go mod download"会并发地下载多个依赖项,从而提高下载速度。它利用"Go Modules"的并发性,从各个源同时下载依赖项。
4.离线下载:如果你的项目处于离线状态,"go mod download" 会尝试使用本地缓存的模块信息,而不会尝试从网络上下载。这对于在没有网络连接的环境中构建项目很有用。

13.3、"go mod vendor"命令说明(将项目的依赖包复制到项目的vendor目录下。vendor目录是一个本地的依赖包存储目录)
1.创建vendor目录:
如果项目中没有vendor目录,"go mod vendor" 将会创建一个。如果已经存在,则会使用已有的vendor目录。
2.复制依赖包到vendor目录:"go mod vendor" 会将项目的所有包复制到vendor目录中。这包括go.mod文件中声明的依赖包。
3.使用本地副本:一旦vendor目录中存在了依赖包,Go编译器将优先使用这些本地副本,而不是从$GOPATH或者模块缓存中下载。
4.更新 vendor 目录:如果go.mod文件中的依赖关系发生变化,你可以运行 "go mod vendor" 以更新 vendor 目录中的本地副本。

13.4、"go get"命令说明(用于下载并安装Go语言的包,默认情况下,"go get"将包安装到$GOPATH目录下)
1.获取并安装包:
"go get"主要用于获取并安装指定的包。你可以通过指定包的导入路径来下载包,例如:go get github.com/example/package,这将下载并安装 github.com/example/package 包及其依赖项。(如果没有指定版本,"go get"将安装包的最新版本)
2.安装特定版本:你可以通过在包的导入路径后面加上特定的版本信息,来下载并安装特定版本的包。例如:go get github.com/example/package@v1.2.3,这将安装 github.com/example/package 的 v1.2.3 版本。
3.在Go Modules的项目中,"go get"不会修改go.mod文件,而是会将依赖项下载到模块缓存中。如果你想更新go.mod文件,你可以使用"go get"后面跟上包的导入路径,例如:go get github.com/example/package@latest,这会更新 go.mod 文件中的依赖版本。

13.5、GOPATH:单一全局工作空间
GOPATH 是一个环境变量,指定了一个全局的工作空间目录,包含了所有的 Go 项目。默认情况下,它包含了三个子目录:bin(可执行文件)、pkg(编译后的包文件)、src(源代码)。
1.依赖管理:以前,Go 使用 GOPATH 来管理项目的依赖关系。当你使用 go get 命令时,它会下载和安装依赖项到 GOPATH 下。
2.导入路径:依赖包的导入路径通常是相对于 GOPATH/src 的路径。
3.全局共享:所有的 Go 项目共享相同的 GOPATH,这可能导致包版本冲突和不同项目之间的干扰。

13.6、Go Modules:项目级别的依赖管理
Go Modules 是一种基于项目的依赖管理方式。每个项目都可以有自己的依赖关系,不再依赖于全局的 GOPATH。
1.go.mod 文件:Go Modules 使用 go.mod 文件来记录项目的依赖关系。go.mod 文件包含了项目的模块信息、依赖包和版本信息。
2.导入路径:Go Modules 不再依赖于 GOPATH,导入路径可以是绝对路径或者相对路径。
3.版本管理:Go Modules 使用语义版本(SemVer)来管理依赖项的版本。每个项目都可以指定自己的依赖版本,避免了全局共享的问题。
4.局部缓存:Go Modules 引入了一个局部缓存(module cache)来存储下载的依赖项,减少了对全局空间的依赖。
5.命令行工具:go mod 是 Go Modules 的命令行工具,用于初始化模块、添加或移除依赖项、更新依赖项等。
在实际开发中,推荐使用 Go Modules 来管理项目的依赖关系,因为它提供了更灵活、更可重复、更清晰的依赖管理方式,同时避免了 GOPATH 的一些限制和问题。

13.7、Go Modules使用介绍:
1.进入项目目录:打开终端,进入你的 Go 项目的根目录。
2.初始化 Go Modules:go mod init your_module_name,这将创建一个 go.mod 文件,记录你的项目的模块信息和当前依赖关系。
3.使用 go get 命令添加新的依赖包,例如:go get github.com/example/package@v1.2.3,安装Gin框架:go get github.com/gin-gonic/gin
4.自动更新 go.mod:每次运行 go get,go.mod 文件都会被自动更新,记录新的依赖项和版本信息。
5.查看当前项目的依赖项:go list -m all,这将列出当前项目的所有依赖项及其版本信息。
6.如果你想更新依赖项到最新版本,可以运行:go get -u,或者,你可以直接指定某个依赖项的新版本:go get github.com/example/package@latest
7.如果你想移除一个依赖项,可以运行:go get -u github.com/example/package@none,这会将该依赖项标记为不使用。
8.运行项目:使用 go run 命令运行你的项目:go run .
9.构建可执行文件:使用 go build 命令构建可执行文件
10.重要命令:
go mod tidy:清理 go.mod 文件,移除不再使用的依赖项。
go mod verify:校验依赖项的哈希值,确保它们没有被篡改。
go mod download:下载项目的所有依赖项到本地缓存。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值