Golang基础语法学习第一周笔记打卡

Go!第一周笔记

2.28

  浏览大佬李文周的博客初步了解go语言,从B站尚硅谷韩顺平老师的视频开始学习,安装go的SDK过程中发现1.20版本与视频演示的1.9版本有以下区别:安装完成得到的bin文件夹中没有godoc.exe;无需配置环境,大大便捷了新手操作过程

第一段go代码:

package main//该文件所在包为main

import "fmt"//引入fmt包

func main() {

    fmt.Println("Hello,world!")//func为关键字,表示函数;main为主函数

}

通过go build命令对该go文件编译,生成.exe文件

C:\Users\zyf>cd G:\GoProject\src\go_code\project01\main

C:\Users\zyf>G:

G:\GoProject\src\go_code\project01\main>dir
 驱动器 G 中的卷是 环境
 卷的序列号是 B0EF-3A2F

 G:\GoProject\src\go_code\project01\main 的目录

2023/02/28  19:20    <DIR>          .
2023/02/28  19:17    <DIR>          ..
2023/02/28  19:20                 0 hello.go
               1 个文件              0 字节
               2 个目录 549,609,558,016 可用字节
G:\GoProject\src\go_code\project01\main>go build hello.go

G:\GoProject\src\go_code\project01\main>dir
 驱动器 G 中的卷是 环境
 卷的序列号是 B0EF-3A2F

 G:\GoProject\src\go_code\project01\main 的目录

2023/02/28  22:14    <DIR>          .
2023/02/28  19:17    <DIR>          ..
2023/02/28  22:14         1,927,680 hello.exe//所得hello.exe
2023/02/28  22:13                80 hello.go
               2 个文件      1,927,760 字节
               2 个目录 549,607,628,800 可用字节

若得到

G:\GoProject\src\go_code\project01\main>go build hello.go
hello.go:1:1: expected 'package', found 'EOF'

则是需要现在vscode里保存(ctrl+s)

go run 可以直接运行!!但是速度不如运行hello.exe

G:\GoProject\src\go_code\project01\main>go run hello.go

Hello,world!

3.1

GoLANG执行流程分析

Hello.go经过go build编译,形成二进制可执行文件hello.exe可直接运行,无需golang的SDK;若直接go run hello.go,编译和运行一步进行,速度慢,需要SDK

在编译时,编译器会将程序运行依赖的库文件包含在可执行文件中,故可执行文件变大很多

另外,编译时可指定所生成的可执行文件名,如:

G:\GoProject\src\go_code\project01\main>go build  -o myhello.exe hello.go

则所得到的可执行文件名为myhello.exe//但在windows中所写文件名后缀必须为exe

另外,若所写程序有错,将会在错误行报错

与视频中旧版VScode不同,新版设置与pycharm类似,新手好上手

语法要求和注意事项!

  1. 程序后缀必须是.go
  2. 区分大小写
  3. Go方法由一条条语句构成,每个语句后不需要分号(Go语言会在每行后自动加分号)
  4. Go编译器是一行行进行编译的,因此一行就写一条语句,不能把多条语句写在同一行,否则报错
  5.  go语言定义的变量或者import的包如果没有使用到,代码不能编译通过。
  6. 大括号都是成对出现的,缺一不可。

转义字符

\n换行 \t制表 \r回车

与视频教程不同,新版本\r不再会用\r后的字符覆盖前面,改为单纯回车

应用实例:

要得

代码:

package main
import "fmt"
func main() {
    fmt.Println("姓名\t年龄\t籍贯\t住址\njohn\t12\t河北\t北京")
}

这里新版本不需要重新建一个文件夹以解决一个包中重复的package main导致的报错

注释

行注释(//)块注释(/* */)和C语言一样,快捷键框中需要注释的内容ctrl+/,但注意块注释不能嵌套(/*/*   */*/是不允许的)

缩进

Tab整体右移一个缩进Shift tab整体左移一个缩进

或者使用go format对代码格式化

如:

package main

import "fmt"

func main() {

    fmt.Println("姓名\t年龄\t籍贯\t住址\njohn\t12\t河北\t北京")

        fmt.Println("姓名\t年龄\t籍贯\t住址\njohn\t12\t河北\t北京")

fmt.Println("姓名\t年龄\t籍贯\t住址\njohn\t12\t河北\t北京")

    fmt.Println("姓名\t年龄\t籍贯\t住址\njohn\t12\t河北\t北京")

}

得到:

G:\GoProject\src\go_code\project01\main>gofmt demo.go

package main

import "fmt"

func main() {

        fmt.Println("姓名\t年龄\t籍贯\t住址\njohn\t12\t河北\t北京")

        fmt.Println("姓名\t年龄\t籍贯\t住址\njohn\t12\t河北\t北京")

        fmt.Println("姓名\t年龄\t籍贯\t住址\njohn\t12\t河北\t北京")

        fmt.Println("姓名\t年龄\t籍贯\t住址\njohn\t12\t河北\t北京")

}//cmd中输出的对齐了,但没有改变原程序格式

所以需要gofmt -w demo.go以改变原程序

//其实现在版本的vscode保存的时候会自动排版,不需要视频中那么复杂了

对C语言,

func main(){

}

func main()

{

}

两种格式都可以,但对go语言,仅前者正确

另外,约定成俗地,一行代码不宜过长

Golang标准库API文档

Golang中文网 在线标准库文档:Go语言标准库文档中文版 | Go语言中文网 | Golang中文社区 | Golang中国

也可以直接再所下载的go文件夹中查看src(源码包)下看具体源代码

调用函数时需要先import包名,然后  包名.函数名  调用

Doss指令

查看目录C:\Users\zyf>dir

切换到其他盘C:\Users\zyf>cd /d G:    切换到G盘

切换到当前盘的其他目录下(使用相对路径和绝对路径演示)

区别:对C:>Users>zyf,目前所在 Users,要转到zyf,绝对路径为cd C:\Users\zyf,相对路径为cd zyf

回到上一级目录cd ..

回到根目录 cd  \

创建新的目录 md 目录名(可同时创建多个目录)

删除目录 rd 目录名

删除目录及其下子目录和文件且不询问 rd  /q/s 目录名

删除目录及其下子目录和文件且询问 rd /s 目录名

文件的操作

创建文件:

echo hello>G:\GoProject\abc.txt

即在goproject目录下创建内容为hello的txt文本

复制文件:

copy abc.txt>G:\Go\efg.txt

即将abc.txt以 efg.txt的名称复制到G:\Go

移动文件:move abc.txt

删除指定文件:del abc.txt

删除所有文件:del *.txt即删除所有txt文件

清屏:cls

退出:exit

小结

两天之内看了前三十节视频,尚硅谷的教程确实非常细致,毫无编程经验的小白都能看懂,但是由于是19年的视频了,版本更新中出现了诸多不同,老师提到的一些需要注意的细节

现在已经不需要拘泥了,更加人性化,可见go语言在短短3年中也有着日新月异的变化。对于之前有一些python学习经验的笔者来说,正常速度已经有些慢了,2倍速刚好。希望自己能坚持下去,看完388节基本语法和二十多个小时的goWeb教程,从这周开始每周打卡!

3.2

变量

  1. 声明(定义)变量//不同于python,必须声明变量类型
  2. 非变量赋值
  3. 使用变量

变量定义的简单案例:

func main() {

    var i int = 1

    fmt.Println("i=", i)

}

1.在go语言中,变量的默认值为0

func main() {

    var i int

    fmt.Println("i=", i)

}

得到i=0

2.在go语言中,可以自动进行变量的类型推导,如:

Var i = 10  则自动认为i的类型为int

3.可以省略var,  var I = 10效果等同于I := 10

但是 :=左侧的变量不能是已经声明过类型的,否则导致编译出错

  1. golang中支持多变量声明
  1. var a,b,c int则声明a,b,c 都是int
  2. var a,b,c = 10,”tom”,5.5
  3. a,b,c := 10,”tom”,5.5

以上三种方式都正确,第二种基本等同于第三种

另外还可以   

 var (

        a = 1

        b = 2

        c = "mary"

    )

变量在该区域的数值可以在同一类型范围内不断变化

变量在同一作用域(暂时理解为在一个函数中或者在代码块)内不能重名

加号的使用

若加号两边都是数据类型,则求和;若两边都是字符,则拼接

整数类型

  1. 有符号类型(用一位来表示符号)int
  2. 无符号类型(默认为正,所有位都用来表示数)uint
  3. Rune等价于int32,但是对于中文有特效

  1. byte在储存单个字符时选用,等价于uint8

查看变量的类型

func main() {

    var a = "mary"

    fmt.Printf("a 的类型是 %T", a)

}

得到:a 的类型是 string

查看占用字节(需要引用unsafe包)

func main() {

    var a = "mary"

    fmt.Printf("a 的类型是 %T ,占用字节为 %d", a, unsafe.Sizeof(a))

}

Go语言在使用整型变量时遵从保小不保大的原则,如描述一个人的年龄255足够了,无需使用int64这种极大的,byte比较合适

补充常识:bit是计算机最小的存储单位,byte是最小的存储单元。1 byte=8 bit

浮点类型

  1. 浮点数的存放方式为:符号位(说明浮点数都有符号)+指数位+尾数位
  2. 尾数位可能丢失,造成精度损失 双精度的损失更小

3.3

3.Golang中的浮点类型有固定范围和长度,不受os(操作系统)影响

4.Golang浮点型默认声明位float64

5.浮点数常量的两种表现形式:(1)十进制数形式  如:5.12  .532(等同于0.532,但是小数点一定不能省略)(2)科学计数法 如:5.1284e3(等同于5128.4),其中e大小写都可以,5.1284e3即5.1283*10**3

6.一般情况下推荐使用float64,精度更高

字符类型

Golang中没有专门的字符类型,储存单个字符(字母)用byte保存

不同于传统用字符组成字符串,go使用字节来组成字符串

这也导致了我们直接输出byte值时其实输出的是字符所对应的码值,如:

func main() {

    var a byte = 'b'

    fmt.Println("a=", a)

}

得到的是a=98

如果我们需要的是对应字符,则需要用格式化输出

func main() {

    var a byte = 'b'

    fmt.Printf("a=%c", a)

}

得到 a=b

而对于中文字符,对应的码值都超过了255,故不能用byte保存,此时就体现出rune对中文的特效了,用其他范围大于255的类型保存也可以

  1. 字符常量是单引号括起来的单个字符
  2. Go语言中存在转义字符(前面已经写到)
  3. Go语言使用utf-8编码规则
  4. 在go中,字符的本质是一个整数(码值)
  5. 也可以反过来给某变量赋一个数字,然后格式化输出会输出其对应的unicode字符
func main() {

    var a rune = 35418

    fmt.Printf("a=%c", a)

}

得到a=

  1. 在Go中,字符也可以运算,相当于其对应的整数运算

反思:go语言使用统一的utf-8编码,很方便,避免出现乱码

每个字符对应唯一码值,进而对应二进制数

布尔类型

  1. 只能取true和false(不同于python True=1,Faulse=0),不能用0或非0整数替代
  2. Bool类型占用一个字节
  3. 适用于逻辑运算,一般用于流程控制

字符串类型

  1. 字符串一旦赋值,就不能修改,go中字符串不可变,但是可以重新赋值
func main() {

    var str = "hello"

    str[0] = 's'//典型错误,与python不同!

    fmt.Println(str)

}

  1. 字符串的两种表现形式(1)双引号会识别转义字符*(2)反引号(``)内以字符串原生形式输出,不识别换行和特殊字符,可以防止攻击、输出源代码

3.4

  1. 字符串的拼接:当加号两边都是字符串时,go认为进行拼接操作

当一个拼接操作很长时,可以分行写:

func main() {

    var str = "hello" + "," +

        "world" + "!"

    fmt.Println(str)

}

然而加号必须在上一行末尾而不能在下一行开头(go默认在每一行末尾加;)

Golang基本数据默认值

整型:0  浮点型:0 字符串:“” 布尔类型:false

Go语言中,%(占位符的使用)

  

 

 

 

常用:十进制整数(%d)布尔值(%t)值的默认格式(%v)相应类型(%T)有小数无指数(%f)字符(%c)单引号括起来的go语法字符字面值,必要时会采用安全的转义表示(%q)

基本数据类型转换

Go语言与java/C不同,在不同的变量赋值需要显式转换,也就是说不能自动转换

func main() {

    var a int = 10

    var b float64 = float64(a)

    fmt.Printf("%T", b)

}

1.转换方式不能直接var a float64 = float64(a),这样就违背了“字符串一旦赋值就不能修改”,故需要向上面的代码一样引入新的变量

2.另外,不同于一些语言在低精度转高精度时可以直接(var b float64 = a),GO中无论低精度(如float32)转高精度(如float64),还是高精度转低精度,都需要严格按照上面代码所展示的格式

3.被转换的是变量储存的数据(即值),变量本身的数据类型没有发生变化

4.转换过程中要注意转变成的数据类型要能容纳下,如果超出范围,编译器不会报错,只会按溢出处理

案例题:

判断:

func main() {

     var a int32 = 10

     var b int64

     var c float32

     b = a + 20

     c = a + 20

}

是否能够编译?        答案:不能,因为a + 20的类型是与a一样为int32,等式两边数据类型不同      解决方法:改为 b = int64(a) +20

案例2

func main() {

    var a int32 = 12

    var b int8

    var c int8

    b = int8(a) + 127 //能通过编译,但是int(a)+127和溢出int8

    c = int8(a) + 128 //不能通过编译,因为128已经超出int8范围

    fmt.Println(b, c)

}

基本数据类型和string的转换

方法一:使用 fmt.sprintf()

案例:

func main() {

    var a int = 99

    var b float64 = 38.7325

    var c bool = true

    var d byte = 'h'

    var e string

    e = fmt.Sprintf("%d", a)

    fmt.Printf("str type %T str=%q\n", e, e)

    e = fmt.Sprintf("%f", b)

    fmt.Printf("str type %T str=%q\n", e, e)

    e = fmt.Sprintf("%t", c)

    fmt.Printf("str type %T str=%q\n", e, e)

    e = fmt.Sprintf("%c", d)

    fmt.Printf("str type %T str=%q\n", e, e)

}

输出得到:

str type string str="99"

str type string str="38.732500"

str type string str="true"

str type string str="h"

可见通过这种方法可以将其他类型转为字符串类型

方法二:使用strconv包函数

func main() {

    var a int = 99

    var b float64 = 38.7325

    var c bool = true

    var e string

    e = strconv.FormatInt(int64(a), 10)

    fmt.Printf("str type %T str=%q\n", e, e)

    e = strconv.FormatFloat(b, 'f', 10, 64)

    fmt.Printf("str type %T str=%q\n", e, e)

    e = strconv.FormatBool(c)

    fmt.Printf("str type %T str=%q\n", e, e)

}

得到:

str type string str="99"

str type string str="38.7325000000"

str type string str="true"

其中,strconv.FormatInt(转换对象,转换成的进制)

strconv.FormatFloat( 转换对象,转换格式(‘f’为最常见的),保留小数位数,原数据类型(例子中表示float64))

strconv.FormatBool(仅转换对象)

另外该包中有Intoa函数,可以实现int转string,但是不能是int64等类型!

这个函数只有转换对象这一个参数,就不做案例了

String转基本数据

func main() {

    var a string = "1314"

    var a1 int64

    var a2 int

    a1, _ = strconv.ParseInt(a, 10, 64)

    a2 = int(a1)

    fmt.Printf("a2 type %T,a2 %v\n", a2, a2)

    var b string = "13.14"

    var b1 float64

    b1, _ = strconv.ParseFloat(b, 64)

    fmt.Printf("b1 type %T,b1 %v\n", b1, b1)

    var c string = "true"

    var c1 bool

    c1, _ = strconv.ParseBool(c)

    fmt.Printf("c1 type %T,c1 %v\n", c1, c1)

}

得到

a2 type int,a2 1314

b1 type float64,b1 13.14

c1 type bool,c1 true

注意:

  1. parse系列函数都会得到两个值,第二个是是否超出范围出错,我们不需要就直接用”_”占位忽略。
  2. ParseFloat有两个参数,对象和转换成的数据类型
  3. ParseInt 有三个参数,对象,进制和转换成的数据类型
  4. PaeseBool只有对象这一个参数

注意事项

在将string类型转化成基本数据类型时,要确保string类型能够转化成有效的数据,如果将“1314“转化成bool类型,则Go将其转化为默认值faulse

  1. string双引号中内容与要转化成的类型对应
  2. 在转化数据时注意不要超出类型的范围

指针

func main() {

    var a int = 1314

    fmt.Printf("a 的地址是%v\n", &a)

    var b *int = &a

    fmt.Printf("b = %v", b)

}

得到

a 的地址是0xc0000180a8

b = 0xc0000180a8
  1. 基本数据类型变量存的就是值,也叫值类型
  2. 获取变量的地址用&,如上
  3. 指针是一个类型,这个类型存的是一个地址,这个地址指向一个存值的空间,而存地址的空间也有一个地址(套娃)
fmt.Printf("b所储存的地址对应的值是%v", *b)

得到:

b所储存的地址对应的值是1314
  1. 由上,获取指针类型所指向的值,使用:*

通过指针改变变量的值:

func main() {

    var a string = "hello"

    var b *string = &a

    *b = "world"

    fmt.Printf("a的值现在是%v", a)

}

得到

a的值现在是world

说明通过指针成功改变了变量a的值,但是a的地址没有改变

3.5

关于指针的细节:

  1. 所有值类型都有其对应的指针类型,形式为 *值类型
  2. 值类型包括之前提到的基本数据类型(int,float,bool,string),数组,结构体struct;

引用类型包括指针,切片(slice),map,管道(chan),接口(interface)

值类型和引用类型

  1. 值类型:变量直接存储值,内存通常在中分配
  2. 引用类型:变量储存一个地址地址对应的空间才是真正存储的数据(值),内存通常在中分配

标识符

  • 概念
  1. Go语言对各种变量、方法、函数等命名时使用的字符序列成为标识符
  2. 凡是自己可以取名的地方都叫标识符
  • 命名规则
  1. 有26字母大小写,0-9数字,_组成
  2. 数字不能开头
  3. 严格区分大小写
  4. 不能包含空格
  5. 对于下划线“_“,其本身在go中是一个特殊的标识符,称为空标识符,可以代表其他任何标识符,但其对应值会被忽略。故仅能占位,不嫩那个作为一般标识符使用
  6. 不能以系统保留关键字作为标识符
  • 命名注意事项
  1. 包名:尽量保持包名与该文件所在文件夹一致,采取有意义的包名,简短且不与标准库冲突
  2. 变量名,函数名,常量名:采用驼峰法(stuName,goProject1)
  3. 若变量名、函数名、常量名首字母大写,则可以被其他的包访问,若首字母小写,则只能在本包使用(大写公用,小写私用)

系统保留关键字

问题:在导入自定义包的过程中,新版需要使用go mod

预定义标识符(包括数据类型和内嵌函数)

运算符

  1. 算术运算符(+-*/)

需要注意的:%取余,++自加(在原数基础上加一),--自减

  1. 赋值运算符(= += -= *=)
  2. 比较运算符(== != > < >= <=)
  3. 逻辑运算符(与或非)
  4. 位运算符(与二进制相关)
  5. 其他运算符

声明:学习资源大部分来自尚硅谷韩顺平老师的视频,侵删;笔者是编程小白,如有错误还请各位大佬指正。 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值