golang basic grammar

一、基础

1.1 条件判断

package main

import "fmt"

func main() {
    var a int = 10

    if a < 20 {
        fmt.Printf("a less 20\n" )
    }
    fmt.Printf("The value of a is  %d\n", a)

    a = 100

    if a < 20 {
        fmt.Printf("a less 20\n" )
    }else{
        fmt.Printf("a not less 20\n" )
    }
    fmt.Printf("The value of a is  %d\n", a)

    a = 20 

    if a < 20 {
        fmt.Printf("a less 20\n" )
    }else if a == 20 {
        fmt.Printf("a == 20\n" )
    }else {
        fmt.Printf("a more 20\n" )
    }
    fmt.Printf("The value of a is  %d\n", a)
}

执行结果

(base) desktop-6rkqqec:study songbw$ go run conditional.go
a less 20
The value of a is 10
a not less 20
The value of a is 100
a == 20
The value of a is 20

1.2 循环

package main

import "fmt"

//Print multiplication table
func gotoTag() {
	for m := 1; m < 10; m++ {
		n := 1
	LOOP:
		if n <= m {
			fmt.Printf("%dx%d=%d ", n, m, m*n)
			n++
			goto LOOP
		} else {
			fmt.Println("")
		}
	}
}

func main() {
	//Similar to the for loop of C
	sum := 0
	for i := 0; i <= 10; i++ {
		sum += i
	}
	fmt.Println(sum)

	//Similar to the while loop of C
	sum = 1
	for sum <= 10 {
		sum += sum
	}
	fmt.Println(sum)

	sum = 1
	for sum <= 10 {
		sum += sum
	}
	fmt.Println(sum)

	//For-each range
	numbers := [6]int{1, 2, 3, 5}
	for i, x := range numbers {
		fmt.Printf("第 %d 位 x 的值 = %d\n", i, x)
	}

	//break without tags
	//This Use of break is similar to C + + or C
	fmt.Println("---- break ----")
	for i := 1; i <= 3; i++ {
		fmt.Printf("i: %d\n", i)
		for i2 := 11; i2 <= 13; i2++ {
			fmt.Printf("i2: %d\n", i2)
			break
		}
	}

	//use tags for break
	fmt.Println("---- break label ----")
reBreak:
	for i := 1; i <= 3; i++ {
		fmt.Printf("i: %d\n", i)
		for i2 := 11; i2 <= 13; i2++ {
			fmt.Printf("i2: %d\n", i2)
			break reBreak
		}
	}

	//continue without tags
	//This Use of continue is similar to C + + or C
	fmt.Println("---- continue ---- ")
	for i := 1; i <= 3; i++ {
		fmt.Printf("i: %d\n", i)
		for i2 := 11; i2 <= 13; i2++ {
			fmt.Printf("i2: %d\n", i2)
			continue
			fmt.Printf("after continue, i2:%d\n", i2)
		}
	}

	//use tags for continue
	fmt.Println("---- continue label ----")
reContinue:
	for i := 1; i <= 3; i++ {
		fmt.Printf("i: %d\n", i)
		for i2 := 11; i2 <= 13; i2++ {
			fmt.Printf("i2: %d\n", i2)
			continue reContinue
			fmt.Printf("after continue, i2:%d\n", i2)
		}
	}
	fmt.Println("Print multiplication table")
	gotoTag()
}

执行结果

(base) localhost:study songbw$ go run csdnLoop.go
55
16
16
第 0 位 x 的值 = 1
第 1 位 x 的值 = 2
第 2 位 x 的值 = 3
第 3 位 x 的值 = 5
第 4 位 x 的值 = 0
第 5 位 x 的值 = 0
---- break ----
i: 1
i2: 11
i: 2
i2: 11
i: 3
i2: 11
---- break label ----
i: 1
i2: 11
---- continue ----
i: 1
i2: 11
i2: 12
i2: 13
i: 2
i2: 11
i2: 12
i2: 13
i: 3
i2: 11
i2: 12
i2: 13
---- continue label ----
i: 1
i2: 11
i: 2
i2: 11
i: 3
i2: 11
Print multiplication table
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
1x4=4 2x4=8 3x4=12 4x4=16
1x5=5 2x5=10 3x5=15 4x5=20 5x5=25
1x6=6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36
1x7=7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49
1x8=8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64
1x9=9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81

解释:
    从代码中可以看出,golang中的contine和break 比c或者c++ 中的功能强大了一丢丢,就是可以加标记,来标识退出或者继续哪一层级的循环,当然或许c或者c++ 中也有这样的功能,可能我不知道,我所接触到的实际工作中不加标记的break和continue已经可以满足需求了

1.3 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("excellent!\n" )
        case grade == "B", grade == "C" :
            fmt.Printf("good\n" )
        case grade == "D" :
            fmt.Printf("pass\n" )
        case grade == "F":
            fmt.Printf("not pass\n" )
        default:
            fmt.Printf("bad\n" );
    }

    fmt.Printf("your level is  %s\n", grade );
}

执行结果

(base) desktop-6rkqqec:study songbw$ go run switch_stat.go
excellent!
your level is A

  switch比较简单,如果switch 后面有类型按类型判断,如果没类型,就按照 bool 值判断,如果一个case满足了,就不会走下一个 case

1.4 map 数据结构

1.4.1 map中用list


package main

import "fmt"

func main() {
	//Initialization
	//var userInfoMap = map[string]string{"name": "songbw", "age": "25"}
	var userInfoMap = map[string]string{}
	userInfoMap["sex"] = "male"
	fmt.Printf("userInfoMap=%v\n", userInfoMap)

	/*var userInfoMap1 map[string]string
	//Not initialized, is an empty map, nil map cannot be used to store key value pairs
	userInfoMap1["name"] = "lucy"
	fmt.Printf("userInfoMap1=%v\n", userInfoMap1)*/

	var userInfoMap1 map[string]string
	//Need to create a map
	userInfoMap1 = make(map[string]string)
	userInfoMap1["name"] = "lucy"
	fmt.Printf("userInfoMap1=%v\n", userInfoMap1)

	//test list
	var userInfoMap2 map[string][]uint
	userInfoMap2 = make(map[string][]uint)
	var score2 []uint
	score2 = append(score2, 98)
	userInfoMap2["songbw"] = score2
	fmt.Printf("userInfoMap2=%v\n", userInfoMap2)
	testListMem := userInfoMap2["songbw"]
	testListMem[0] = 100
	fmt.Printf("after update 98 to 100=%v\n", userInfoMap2)

	testListMem = append(testListMem, 1)

	fmt.Printf("after add data 1,userInfoMap2, wrong=%v\n", userInfoMap2)

	userInfoMap2["songbw"] = testListMem
	fmt.Printf("after add data 1,userInfoMap2, right=%v\n", userInfoMap2)

}

执行结果

userInfoMap=map[sex:male]
userInfoMap1=map[name:lucy]
userInfoMap2=map[songbw:[98]]
after update 98 to 100=map[songbw:[100]]
after add data 1,userInfoMap2, wrong=map[songbw:[100]]
after add data 1,userInfoMap2, right=map[songbw:[100 1]]

说明:
对于 map userInfoMap2
a、
修改 map userInfoMap2 中的数据是没问题的,显然将98修改成了100,那是因为,我们拿到的 list 可能是引用

b、
拿出 songbw 对应的 list 并添加数据,发现map中,songbw 对应的list 的数据,并没有增加,正确的做法,是把 list 重新赋值给 map ,如下

userInfoMap2["songbw"] = testListMem

我是这么理解这个问题的:
  songbw 这个 key ,实际可能存的是 list 的地址,如果改动地址里面对应的元素,那没问题,songbw 对应的 list中的数据,会发生相应的改变,但是如果添加数据的话, list 的空间可能会不够用,所以可能重新申请内存,会产生新的 list 地址,那么显然,map中的 list 地址还是以前的啊,要想变成新的 list 地址,需要重新赋值啊

1.4.2 map中用过指针

package main

import "fmt"

type PoolConfig struct {
	EnableOverflow bool
	GroupID        []int
}

func main() {
	var tmpPPoolConfig = make(map[int]*PoolConfig)
	tmpPPoolConfig[10] = &PoolConfig{
		EnableOverflow: false,
		GroupID:        []int{100},
	}
	pGroupConfig := tmpPPoolConfig[10]
	pGroupConfig.GroupID = append(pGroupConfig.GroupID, 22)

	fmt.Printf("pGroupConfig=%v\n", pGroupConfig)
	fmt.Printf("tmpPPoolConfig=%v\n", tmpPPoolConfig[10].GroupID)

	var tmpPoolConfig = make(map[int]PoolConfig)
	tmpPoolConfig[20] = PoolConfig{
		EnableOverflow: false,
		GroupID:        []int{200},
	}
	groupConfig := tmpPoolConfig[20]
	groupConfig.GroupID = append(groupConfig.GroupID, 32)

	fmt.Printf("groupConfig=%v\n", groupConfig)
	fmt.Printf("wrong tmpPoolConfig=%v\n", tmpPoolConfig[20].GroupID)

	tmpPoolConfig[20] = groupConfig
	fmt.Printf("right tmpPoolConfig=%v\n", tmpPoolConfig[20].GroupID)

}

执行结果:

pGroupConfig=&{false [100 22]}
tmpPPoolConfig=[100 22]
groupConfig={false [200 32]}
wrong tmpPoolConfig=[200]
right tmpPoolConfig=[200 32]

说明:
  这个例子说明了,golang 的指针和c++ 的指针,本质上是一样,显然,对于 map tmpPPoolConfig ,value值存的是指针,数据就可以加进去,因为访问的是内存,而对于 map tmpPoolConfig,数据就要通过重新赋值的方式,才能够加进去

二 编译

2.1 go build

golang 代码写完后,如何生成可执行程序呢?
1、要把你写的golang代码放到 src 目录下,包括第三方源代码
2、设置环境变量 GOPATH是src的上一级目录
3、保证自己代码中import 过来的包是可以找到的,那么怎么算是可以找到的呢?
执行

ll $GOPATH/src/import下的目录

是可以找到相应的包的,这里要注意,import 后面的仅仅是包所在的目录而已,具体的包是在这个目录下面的,因为包所在的目录可以和包不是一个名字的,具体例子吧:
GOPATH设置如下

(base) localhost:bin songbw$ echo $GOPATH
/Users/songbw/OwnProject/go/smallCCNP

import 语句如下:

import (
       "pkg/api"
   )

如下

(base) localhost:smallCCNP songbw$ ll $GOPATH/src/pkg/api
total 8
-rw-r--r--  1 songbw  staff  303  3 29 10:15 zapis.go

是存在的,并且虽然引入的是api目录,但文件 zapis.go中标识的包是 package zapis ,所以import 的是 pkg/api ,而不是 pkg/zapis
4、使用 go build 生成可执行程序

go build -o smallCCNP pkg

-o 不解释了,和c/c++ 中的一样,pkg就是golang代码所在的目录,这条命令可以在终端的任何一个位置执行,因为,pkg会拼上 $GOPATH/src,而我的源代码就是放在 $GOPATH/src/pkg下面的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值