这是我参与「第五届青训营 」伴学笔记创作活动的第1天。
前言
个人目前是一名大一新生,只有C语言基础以及接触过一些java,了解过OOP。Go对我来说是一门全新的高级语言,我会试图从自己的编程基础上去理解认知它。同时,这也是我第一次写类似于博客的东西,非常乐于接受各位的批评与指正。
基础语法篇
1.熟悉但又不熟悉的"Hello,World"
package main 指的是这个程序是main包的一部分 也就是程序的入口包 这个文件也就是程序的入口文件
import表示导入了标准库里的fmt包
func 用来声明函数main
fmt.Println表示调用了fmt包里的Println方法
值得注意的是,切勿把fmt.Println直接打成了println。这两者均合法但不同。如果你导入了fmt包但是用println方法输出,编译器会报错,因为fmt导入但并未被使用,未被使用的变量或导入会被Go编译器认为是一个error。 同时,编译器会给出修改方案,其中一个修改方案是取消导入fmt包,修改后的代码如下:
你会发现,println在Go中不需要导入任何包即可使用,实际上println 属于 builtin 包,builtin包属于Go语言内置的,其中包含一些常量、变量与函数等。至于println与fmt.Println的具体区别,详见Go语言的官方文档。
2.变量类型
go语言中字符串是内置类型 可以直接用加号拼接,也能直接用等于号比较字符串
变量声明:
var name = content
如果以这种方式声明变量,go会自动推导变量的类型
同时也可以显式的声明变量类型
var name type = content
另一种声明变量的方式是
name := content
常量声明:
const name (type) = content
同理会根据上下文自动确定常量类型(如果不主动声明)
3.if else条件语句
go的if else与c没什么不同 只是布尔表达式不需要加括号,并且后面必须加大括号
4.循环(for)
go只有for循环 并且和C几乎一样
break与contine等在for循环里的作用也和C一样
5.分支(switch)
和C几乎相同 switch后面的变量名不需要括号(golang的switch后的变量可以是多种 字符串 结构体等) 和C不同的地方在于case分支里不需要加break也可以跳出分支,如果需要继续执行下一个case,则需要句末使用fallthrough。fallthrough 不会判断下一条 case 的表达式结果是否为 true,强制执行。 switch后可以不跟变量名,而是在case后跟条件 这样可以代替if else语句使用且更容易理解,如
得到结果:
6.数组
声明数组:var name [len]type
好像golang没有变长数组 但是可以在初始化时用: var nameArray = […]type{content1,content2} 这种方式来让编译器自动推导数组的长度
没有被初始化的数组会被自动初始化为0 nil 等等
7.切片slice
切片类似于一个可变长度的数组 但是其类型和数组不同
使用make语句
name :=make([]type,len) 来创建一个切片
使用 append 语句
slicename = append(slicename,content) 来追加元素
append 的返回值是一个切片(如果发生了扩容那就是一个新的数组) 所以必须要赋值回去才能使原数组扩容
使用copy语句在两个切片之间拷贝数据
copy= (slice1,slice2)//slice2 的数据拷贝到slice1中,长度取两者较小的。
slice还有切片操作
slicename [positon1:position2]
意为取切片中的2-4(左闭右开)个元素,即给切片“切片”。同样的操作也可以做到给数组“切片”。
8.map
之前没有接触到过map这种语法
但是经过了解之后 发现其和数学中的一种概念很像——映射 或者说函数
先来说说map的定义:
可以使用make方法来定义一个map
name :=make(map[type1]type2)
前面那个type指的是key的类型
后面那个type是valve的类型,二者可以相同也可以不同。
那么问题来了 key和valve是什么?
你可以把他想象成函数 key可以比作你输入的自变量x,valve可以比作得到的因变量y,每一个key仅唯一对应一个valve。
map的使用:
初始化map:
name [key]=value
key 和valve的类型需要分别符合type1、type2
使用时,name [key] 的实际值即为valve
不同的key对应不同的valve
如何判断某个键是否存在?
go可以用 valve,ok= mapname [key] 来检测某个键是否有对应的valve,并将检测结果赋值给ok(检测结果值为true/false)
delete () 删除键值对:
可以使用delete(mapname,key) 来删除对应的某组键值对,如17行
直接输出mapname会以map [key1:value1 key2:value2…] 的方式列出所有的键值对
9.range
同for一起使用 可以进行很方便的迭代数组、切片等的元素
如for key (index), value := range map/array
key/value 是可以省略的: for key :=range map
或用 _ 替代对应的位置
10.数组
和c区别不大 就不多说了
11.函数
和c大体相似 但是声明格式略有不同
func name(parameter param_type)(return1_type,return2_type){
}
参数的类型是后置的,返回类型紧跟括号外,并可以返回多个值(如不需要可省)
12.指针
和C类似,但更简单,且有所限制,一般不能对地址直接进行操作。
13.结构体
和C类似
声明结构为:type structname struct{}
14. 结构体方法
众所周知,C的结构体是不能传入函数的(可以传入函数指针)
但是go可以,声明方式为:
首先定义一种结构体
type structname struct{
name1 type1
name2 type2
}
随后便可以声明结构体方法
func (struct_name structname)func_name(parameter type)(return_type){
}
因为结构体可以使用.来访问结构体的元素
导致了可以:struct_name.func_name{argument}这样调用结构体方法。
看起来是不是很眼熟?对,非常的像java中类的定义 如: System.out.println
开篇的fmt.Println同样是这样调用的,只不过fmt是标准库的包而不是你定义的。
这么一看,这样似乎和java等OOP语言的类这个概念非常相似。这也是我对Go语言产生兴趣的地方,go是介于OOP与非OOP之间的语言。
15.Go的标准库
Go同样拥有强大的标准库,可以使用import导入标准库的包并使用包中的方法,以此来实现日期时间的处理,Json解析等操作。
引用/参考
该文章部分内容引用或参考了以下课程或文章:
- 走进 Go 语言基础语言
- Go语言教程
- Go语言标准库文档中文版 | Go语言中文网 | Golang中文社区 | Golang中国
- HikariLan荷兰星辰的博客:从Java的角度初识Go语言|青训营笔记
分发
This work is licensed under CC BY-SA 4.0