GO基本语法学习之路 Day1

前言

计划是花三四天把基本的语法学完,然后开始学习6.824了,后面的编程都需要用GO了。

GO基本语法学习之路 Day1

1. 变量声明

变量声明有四种方式:

  • var a int // 方法一:声明一个变量 默认值是0
  • var b int = 100 // 方法二:声明一个变量,初始化一个值
  • var c = 100 // 方法三:初始化的时候,省去数据类型,通过值匹配当前的变量数据类型
  • e := 100 // 方法四:(常用的方法)省去var关键字,直接自动匹配 不支持全局

声明多个变量:

var xx, yy = 100, "JehanRio"	// 单行
var (							// 多行
		vv int = 100
		jj bool = true
		kk = 3.14
	)

2. const与iota

常量的创建一样:const length = 10
iota类似于C/C++中的枚举类型,进行累加,只能在const中使用

const (
	// 在const()添加一个关键字 iota,每行的iota都会累加一,第一行是默认0(只能出现在const的括号中)
	CHONGQING = 7
	CHENGDU 
	NANJING = 0
	SHANGHAI = iota*10	// 第n行,iota的初始值就是n-1
	SHENZHEN
)

3. 函数

基本方式:

func foo1(a string, b string) int {
	fmt.Println("a=", a)
	fmt.Println("b=", b)
	c := 100 
	return c
}

当然,还能返回多个值,像python一样

func foo2(a string, b string) (int, int) {
	return 1, 2
}

返回多个返回值,有形参名的, 默认值为0

func foo3() (r1 int, r2 int) {
	// 给有名称的返回值赋值
	r1 = 1000
	r2 = 2000
	return
}

对于大量重复的参数类型 可以优化,放到最后一个参数声明即可

func foo4() (r1, r2 int) {
	r1 = 3000
	r2 = 4000
	return 	// 返回的时候直接return就行,不需要加再加r1, r2
}

4. 导包

GO语言是以包为单位的,对于主文件来说,必须要有package main,相当于main函数一样。对于其他文件包,只需要package 文件名即可。

在Go语言入门环境搭建中有两个重要的概念GOPATH和GOROOT,其中GOROOT是我们安装的go路径例如D:\Go,将这个路径设置到环境变量就配置好了GO目录的安装路径了。PATH环境变量就是%GOROOT%\bin路径,如D:\Go\bin路径。
而GOPATH则是我们的工作目录,就是写代码的目录,在环境变量中配置之后,我们编译源代码等生成的文件都会放到这个目录下,这个目录下我们一般会新建三个文件夹:src、pkg、bin:

  • src 目录存放的是我们的go源代码,不同工程项目的代码以包名区分。
  • pkg 编译后生成的文件(比如:.a)
  • bin文件夹存放go install命名生成的可执行文件,

Go.mod的好处
在开发中,我们可能会配置多个GOPATH,每个project使用不同的GOPATH。多个project会导致多个GOPATH目录,而go优先使用第一个GOPATH目录,会导致编译冲突,解决办法就是使用如下目录将多个project或工具组件都放在GOPATH的src目录下,此时GOBIN可以为空。GOPATH目录和GOPATH下的src不应该添加到源代码管理中,而是各个project目录myApp1、myApp2、myApp3各自独立进行源代码管理:

goWorkSpace     // goWorkSpace为GOPATH目录
  -- bin
     -- myApp1  // 编译生成
     -- myApp2  // 编译生成
     -- myApp3  // 编译生成
  -- pkg
  -- src
     -- common 1
     -- common 2
     -- common utils ...
     -- myApp1     // project1
        -- models
        -- controllers
        -- others
        -- main.go 
     -- myApp2     // project2
        -- models
        -- controllers
        -- others
        -- main.go 
     -- myApp3     // project3
        -- models
        -- controllers
        -- others
        -- main.go 

下面是几种导包的方式
在这里插入图片描述
在这里插入图片描述
同时,对于其他包来说,函数第一个字母必须大写,否则则是私有的,不能被外面使用。

5. 指针

和C/C++一样,GO的默认是值传递,同样也有指针,用法一样

func changeValue(p *int) {
	*p = 10
}
func main() {
	var a = 1
	changeValue(&a)
	fmt.Println("a = ", a)
}

6. defer

相当于C++的析构函数,在某个函数结束前执行的函数,defer关键字后面可以跟函数语句执行。注意:return先,defer后

func main()  {
	defer fmt.Println("main end1")
	defer fmt.Println("main end2")	
	
	fmt.Println("main!")
}

在这里插入图片描述
defer会压栈,所以执行顺序是反的。

7. 动态数组

数组的定义

var myArray1 [10]int
myArray2 := [10]int{1,2,3,4}

for循环和C语言差不多,这里还有一个range,类似于python的enumerate

package main
import "fmt"
func main()  {
	var myArray1 [10]int
	myArray2 := [10]int{1,2,3,4}
	for i := 0; i < len(myArray1); i++ {
		fmt.Println(myArray1[i], myArray2[i])
	}
	for index, value := range myArray2 {
		fmt.Println("Index = ", index, "value = ", value)
	}
}

在这里插入图片描述
注意,函数里面的数组传递,依旧是值传递,这一点和C不一样!

所以,我们需要修改数组的值的时候,需要用动态数组。动态数组的数组长度不能设置,必须是空

package main
import "fmt"

func printArray(myArray []int) {	// 引用传递,不同元素长度的动态数组形参是一致的
	for _, value := range(myArray) {	// _代表匿名,访问不了
		fmt.Println("value = ", value)
	}
	myArray[0] = 100
}

func main() {
	myArray := []int{1,2,3,4}	// 空心[]代表动态数组,切片,slice
	fmt.Printf("type is %T\n", myArray)
	printArray(myArray)
	for _, value := range(myArray) {	// _代表匿名,访问不了
		fmt.Println("value = ", value)
	} 
}

在这里插入图片描述
若函数是动态数组方式,而你的数组又是固定长度的数组,你传参的时候需要这样:printArray(myArray2[:]),变为引用传递,这样也能修改值

8. 切片

8.1 切片的定义

Go 语言切片是对数组的抽象。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

slice的4种定义方式

package main
import "fmt"

func main() {
	slice1 := []int{1,2,3}	// 声明slice1,并且初始化
	
	var slice2 []int		// 声明slice2是一个切片,但是没有分配空间
	slice2 = make([]int, 3)	// 分配空间,默认值是0

	var slice3 []int = make([]int, 3)

	slice4 := make([]int, 3)	// 通过:=推导(常用方式)

	fmt.Printf("len = %d, slice = %v\n", len(slice1), slice1)
	fmt.Printf("len = %d, slice = %v\n", len(slice2), slice2)
	fmt.Printf("len = %d, slice = %v\n", len(slice3), slice3)
	fmt.Printf("len = %d, slice = %v\n", len(slice4), slice4)
	
}

8.2 切片的追加与截取

var slice3 []int = make([]int, 3, 5)	// 设置容量为5
fmt.Printf("len = %d, slice = %v, cap = %d\n", len(slice3), slice3, cap(slice3))

追加

var slice3 []int = make([]int, 3, 5)
slice3 = append(slice3, 2)
fmt.Println("slice3 = %v", slice3)	// 若超过容量了,容量会翻倍(与vector一致)

截取
这一块基本和python一致

package main


import "fmt"


func main() {
   /* 创建切片 */
   numbers := []int{0,1,2,3,4,5,6,7,8}   
   printSlice(numbers)


   /* 打印原始切片 */
   fmt.Println("numbers ==", numbers)


   /* 打印子切片从索引1(包含) 到索引4(不包含)*/
   fmt.Println("numbers[1:4] ==", numbers[1:4])


   /* 默认下限为 0*/
   fmt.Println("numbers[:3] ==", numbers[:3])


   /* 默认上限为 len(s)*/
   fmt.Println("numbers[4:] ==", numbers[4:])


   numbers1 := make([]int,0,5)
   printSlice(numbers1)


   /* 打印子切片从索引  0(包含) 到索引 2(不包含) */
   number2 := numbers[:2]
   printSlice(number2)


   /* 打印子切片从索引 2(包含) 到索引 5(不包含) */
   number3 := numbers[2:5]
   printSlice(number3)


}


func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

以上结果为:

len=9 cap=9 slice=[0 1 2 3 4 5 6 7 8]
numbers == [0 1 2 3 4 5 6 7 8]
numbers[1:4] == [1 2 3]
numbers[:3] == [0 1 2]
numbers[4:] == [4 5 6 7 8]
len=0 cap=5 slice=[]
len=2 cap=9 slice=[0 1]
len=3 cap=7 slice=[2 3 4]

8.3 append() 和 copy() 函数

如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。

下面的代码描述了从拷贝切片的 copy 方法和向切片追加新元素的 append 方法。

package main


import "fmt"


func main() {
   var numbers []int
   printSlice(numbers)


   /* 允许追加空切片 */
   numbers = append(numbers, 0)
   printSlice(numbers)


   /* 向切片添加一个元素 */
   numbers = append(numbers, 1)
   printSlice(numbers)


   /* 同时添加多个元素 */
   numbers = append(numbers, 2,3,4)
   printSlice(numbers)


   /* 创建切片 numbers1 是之前切片的两倍容量 */
   numbers1 := make([]int, len(numbers), (cap(numbers))*2)


   /* 拷贝 numbers 的内容到 numbers1 */
   copy(numbers1,numbers)
   printSlice(numbers1)   
}


func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

以上结果为:

len=0 cap=0 slice=[]
len=1 cap=1 slice=[0]
len=2 cap=2 slice=[0 1]
len=5 cap=6 slice=[0 1 2 3 4]
len=5 cap=12 slice=[0 1 2 3 4]

9. map

就是C中的map,键值对,底层是哈希表。当然,map也是引用传递。

package main
import (
    "fmt"
)

func main() {
    //第一种声明
    var test1 map[string]string
    //在使用map前,需要先make,make的作用就是给map分配数据空间
    test1 = make(map[string]string, 10) 
    test1["one"] = "php"
    test1["two"] = "golang"
    test1["three"] = "java"
    fmt.Println(test1) //map[two:golang three:java one:php]


    //第二种声明
    test2 := make(map[string]string)
    test2["one"] = "php"
    test2["two"] = "golang"
    test2["three"] = "java"
    fmt.Println(test2) //map[one:php two:golang three:java]

    //第三种声明
    test3 := map[string]string{
        "one" : "php",
        "two" : "golang",
        "three" : "java",
    }
    fmt.Println(test3) //map[one:php two:golang three:java]


    
    language := make(map[string]map[string]string)
    language["php"] = make(map[string]string, 2)
    language["php"]["id"] = "1"
    language["php"]["desc"] = "php是世界上最美的语言"
    language["golang"] = make(map[string]string, 2)
    language["golang"]["id"] = "2"
    language["golang"]["desc"] = "golang抗并发非常good"
    
    fmt.Println(language) //map[php:map[id:1 desc:php是世界上最美的语言] golang:map[id:2 desc:golang抗并发非常good]]


    //增删改查
    // val, key := language["php"]  //查找是否有php这个子元素
    // if key {
    //     fmt.Printf("%v", val)
    // } else {
    //     fmt.Printf("no");
    // }

    //language["php"]["id"] = "3" //修改了php子元素的id值
    //language["php"]["nickname"] = "啪啪啪" //增加php元素里的nickname值
    //delete(language, "php")  //删除了php子元素
    fmt.Println(language)
}

Reference

【Go基础】Go自定义导入包以及Go常用命令
8小时转职Golang工程师(如果你想低成本学习Go语言)

基于上面的引用内容,golang的基础语法学习可以参考以下几个步骤: 1. 首先,我们需要安装golang的开发环境。你可以直接进入官网(https://go.dev/)下载并安装golang的解释器。 2. 接下来,我们可以开始学习golang的语法。从上面的引用内容可以看出,golang的语法和Java的结构很相似,所以如果你之前有Java编程的经验,可以借鉴一些类比来学习。但是即使你没有Java的经验,也不用担心,golang的语法相对简单并且易于学习。 3. 另外,golang被称为“云计算时代的开发利器”,在使用过程中给人一种优雅、亲切、舒适的感觉。因此,在学习golang的过程中,你可能会发现它的语法设计和使用方式非常人性化。 综上所述,学习golang的基础语法可以通过安装开发环境、参考Java的结构以及体验其优雅、亲切、舒适的特点来进行。希望这些信息能够帮助你开始学习golang的基础语法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [一文看完golang基础语法](https://blog.csdn.net/qq_35889508/article/details/128125279)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值