[ Go语言基础语法 | 青训营笔记 ]

54 阅读4分钟

GO语言是一门很有意思的语言,个人之前学过一点C、C++语言,有一定的基础。在青训营第一课中,讲述了Go的基本语法,我在这里做一点小小的笔记。

Go语言需要包,程序从main包开始运行

package main

然后通过导入路径使用包(此处使用fmt(format),math/rand(math and random))

import(
    "fmt"
    "math/rand"
)

将其构建为一个基本的程序

package main
import(
    "fmt"
    "math/rand"
)
func main(){
    fmt.Println("A rand Number is ",rand.Intn(10))
}

Tips:了解一下rand.Seed(time.Now().UnixNano())

组合导入&单个导入

import(
    "fmt"
    "time/rand"
)

AND

import "fmt"
import "math"

运用包内的方法

Go语言的开发者非常喜欢首字母大写,所以包内的方法,每个单词的首字母都是大写的,比如fmt.Println()或者是math.Pi

函数

Go语言中的类型在变量名之后

基本格式

func 函数名(变量1 类型1,变量2 类型2,……)返回值类型{}

func add(x int,y int)int{
    return x+y
}

如果两个变量相同,那么也可以这样

func 函数名(变量1 变量2 共同的类型,……)返回值类型{}

func add(x,y int)int{
    return x+y
}

返回多个值还能

func swap(x,y string)(string,string){
    return y,x
}

然后这样调用

package main

import "fmt"

func swap(x, y string) (string, string) {
	return y, x
}

func main() {
	a, b := "A", "B"
	fmt.Println(a, b)
	a, b =swap(a,b)
	fmt.Println(a,b)
}

Go语言还支持命名返回值,感觉不如写写在return处

func test2(num int) (res int) {
	res = num + 1
	return //可不写返回变量名,但return是必须的
}
func test3(num int) (res int) {
	res = num + 1
	return num//重新指定返回值
}
func main() {
	fmt.Println("输出结果是:", test2(1))
	fmt.Println("输出结果是:", test3(1))
}

变量

变量的命名方式var 名字 数据类型,这表明Go是一种强类型语言

当不给初始化的时候,复制为空或者是0(false)

变量可以批量初始化,还可以自动识别类型进行赋值,如果你懒到不想用var那么可以使用:=

i,j :=1,2
var i,j =1,2
var i,j int=1,2

image.png

Tips:函数外的每个语句都必须以关键字开始(varfunc 等等),因此 := 结构不能在函数外使用。

类型转换

必须要显示转换哦。不过当右边包含未指明类型的数值常量时,新变量的类型就可能是 intfloat64 或 complex128 了,这取决于常量的精度

常量和Java&C++一样,使用关键词const,并且不能用:=

循环

这里只有for循环哦

话说我用C++的时候也没有几次用while的,do——while更是少见

首先是经典的for

for i := 0; i < 10; i++ {
   sum += i
}

哎,while以for形式出现了

package main

func main() {
	sum := 1
	for sum <= 100 {
		sum++
		print("Still missing Kamisato Ayaka\n")
	}
}

我觉得不会有人写无限循环

for{
}

条件判断

if语句

和C&Java的一模一样哦,只不过可以在表达式内执行一个简单的语句(能且仅能)

func pow(x, n, lim float64) float64 {
	if v := math.Pow(x, n); v < lim {
		return v
	}
	return lim
}

if-else

if 条件{
}else{
}

switch

此处贴上菜鸟教程的代码,真的很不错

package main  
  
import "fmt"  
  
func main() {  
   /* 定义局部变量 */  
   var grade string = "B"  
   var marks int = 90  
  
   switch marks {  
      case 90: grade = "A"  
      case 80: grade = "B"  
      case 50,60,70 : grade = "C"  
      default: grade = "D"    
   }  
  
   switch {  
      case grade == "A" :  
         fmt.Printf("优秀!\n" )      
      case grade == "B", grade == "C" :  
         fmt.Printf("良好\n" )        
      case grade == "D" :  
         fmt.Printf("及格\n" )        
      case grade == "F":  
         fmt.Printf("不及格\n" )  
      default:  
         fmt.Printf("差\n" );  
   }  
   fmt.Printf("你的等级是 %s\n", grade );

defer,新东西耶

推迟的函数调用会被压入一个栈中。当外层函数返回时,被推迟的函数会按照后进先出的顺序调用。

package main

import "fmt"

func main() {
	fmt.Println("Start")

	for i := 0; i < 5; i++ {
		defer fmt.Println(i)
	}

	fmt.Println("END")
}

输出结果

Start
END
4
3
2
1
0

指针

这个和C是类似的,指针内保存了值的内存地址。

使用&来取值的地址,*:通过指针进行取值

Go语言没有指针运算

结构体

结构体的基本形式

type 名字 struct{
    变量名1 变量类型1
    变量名2 变量类型2
    ……
}

访问结构体内部的东西时和C语言是类似的,需要通过加.号进行访问

还有Go语言的语法糖:需要用指针来引用结构体内部元素时,可以使用(*p).x也可以使用p.x,就像C语言中的(*p).xp->x

结构体赋值

可以按照顺序赋值,如果我们有下面这种形式

type point struct{
    x int
    y int
}

那么我可以用以下几种方式赋值

a=point{1,1}//代表点(1,1)
b=point{x:1}//代表点(1,0)
c=point{}//代表点(0,0)

数组

举个简单的例子var a [5]int代表有一个数组,名字叫做a,它有5个元素,每一个元素的类型是int

但是数组的长度不能改变,因此Go语言提供了切片

切片

数组的大小是固定的,但是切片为数组的使用提供了灵活的视角

[]int代表了一个数据类型为int的切片,切片使用:来界定上界和下界,并且是左闭右开的区间。

由于切片是对数组的引用,所以当原数组改变时,切片也会随之改变(感觉很像Excel里面的数据透视表耶)

切片的创建方式

可以使用make([]int,0,5)来创建一个数据类型为int的有5个元素的数组,并且有长度为0的切片引用它

切片的append方法

下面的例子可以体现,一定要记得使用s=append

var s []int//[]
s=append(s,0)//[0]
s=append(s,1,2,3)//[0 1 2 3]

range

for循环的range形式可以遍历切片或者是映射

当用for循环遍历切片时,每次迭代会返回两个值,分别是index和value,我们可以在对应位置使用_对其进行忽略

map(或称为映射)

map的语法和结构体类似,但是必须有key,当然如果你不用key,而使用map的名字的话,输出的是整个map(map是无序的)

map的创建方式

var m = map[int]string m:=make(map[int]string)

创建了一个key为int,value为string类型的map

修改map

如果需要修改map中的元素

插入和修改m[key]=value

删除delete(m,key)

双赋值(特色)

例如key不在map里面,那么有

v, ok := m[key]
fmt.Println( v,ok)

输出结果

0 false