go语言基础语法
变量
var a = "initial"
var b, c int = 1, 2
var d = true
var e float64
f := float32(e)
g := a + "foo"
1.var关键字
go语言声明变量的一般形式是使用var关键字,name是变量名,type是变量的类型。需要注意的是,go语言和许多编程语言不同,它在声明变量时是将变量的类型放在变量的名称之后。
var b, c int = 1, 2
- =是赋值,:=是声明变量并赋值
var a
a = 100
var b = 100
var c int = 100
d := 100 // := 是声明并赋值,并且系统自动推断类型,不需要var关键字
//会报错,重复声明变量a
var a int
a := 1
- float32和float64 float32,也即我们常说的单精度,存储占用4个字节,32位,其中1位用来表示符号,8位用来表示指数,剩下的23位表示尾数。 float64,也即我们常说的双精度,存储占用8个字节,64位,其中1位用来表示符号,11位用来表示指数,剩下的52位表示尾数。
import "fmt"
var myFloat01 float32 = 100000182
var myFloat02 float32 = 100000187
func main() {
fmt.Println("myfloat: ", myFloat01)
fmt.Println("myfloat: ", myFloat01 + 5)
fmt.Println(myfloat02 == myfloat01 + 5) //false
}
由于精度问题,第八位无法表示,所以运算后第七位的值,就会变得不精确。
- rune go语言的编码是按照UTF-8编码规则进行编码的,所以如果我们按照一个个字节的方式去处理中文字符串会导致乱码。所以go语言引进了rune的概念(其实是int32类型的别名)。在我们对字符串进行处理的时候只需要将字符串通过range去遍历,会按照rune为单位自动去处理。
判断语句
if 7%2 == 0 {
...
} else {
...
}
go语言中的判断语句与java类似,不同的是go语言的if语句后面没有括号,并且后面的大括号是必须要写的不能省略。
循环
func main() {
i := 1
for {
...
break
}
for j := 7; j < 9; j++ {
...
}
for i <= 3 {
...
i += 1
}
}
go里面只有for一种循环。最简单的for循环就是在for后面什么都不写,代表一个死循环。
switch语句
func main() {
a := 2
switch a {
case 1:
...
case 2:
...
case 3:
...
case 4, 5:
...
default:
...
}
t := time.Now()
switch {
case t.Hour() > 12:
...
default:
...
}
}
在java里,switch case如果不加break的话就会继续往下跑完所有的case,在go语言里面是不用加break的。 go语言的switch可以使用任意的变量类型,甚至可以用来取代if else语句,可以在switch后面不加任何的变量,然后在case里面写条件分支,这样代码会比多个if else更清晰。
切片
func main() {
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
s = append(s, "d)
s = append(s, "e", "f")
s[2, 5] // [c d e]
}
切片不同于数组,可以任意更改长度,我们可以用make来创建一个切片,使用append来追加元素。注意append用法,必须把append结果赋值为原数组。 slice拥有和python一样的切片操作,比如这个代表取出第二个到第五个位置的元素,不包括第五个元素。这里不支持负数索引
map
func main() {
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
m2 := map[string]int{"one" : 1, "two", 2}
var m3 = map[string]int{"one" : 1, "two", 2}
}
map(哈希表),我们可以用make创建一个空map,这里会需要两个类型,第一个是那个key的类型,这里是string,另一个是value的类型,这里是int。 golang的map是完全无序的,遍历的时候不会按照字母顺序,也不会按照插入顺序输出,而是随机顺序。
range
func main() {
nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {
sum += num
if num == 2 {
...
}
}
}
对于一个slice或者一个map的话,我们可以用range来快速遍历,这样代码能够更加简洁。range遍历的时候,对于数组会返回两个值,第一个是索引,第二个是对应位置的值,如果我们不需要索引的话,我们可以用下划线来忽略。
函数
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
golang的变量类型是后置的,返回类型也是如此。golang里面的函数原生支持返回多个值,在实际的业务逻辑代码里面几乎所有的函数都返回两个值,第一个是真正的返回结果,第二个值的一个错误信息。
结构体方法
type user struct {
name string
password string
}
func (u user) checkPassword(password string) bool {
return u.password == password
}
func (u *user) resetPassword(password string) {
u.password = password
}
类似于类成员函数,如果不带指针,实际上操作的是一个拷贝,无法对结构体进行修改
错误处理
func findUser(users[] user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil
}
}
return nil, errors.New("not found")
}
不同于java里的异常,go语言的处理方式,能够很清晰地知道哪个函数返回了错误,并且能用简单地if else来处理。