Go语法简略 - 基础篇
优秀的程序员应该不限于只用一两种语言,对各种语言都要有猎涉,这样才能在合适的应用下选择最合适的语言。但优秀的程序员至少需要精通一到两种语言,在众多的编程语言中,我选择 Go 和 Swift 作为自己之后20年内的主要编程语言。
本文主要记录 Go 的基础语法,方便查询。
0. Hello world
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界") // 语句结尾没有分号,当然这个也可以有
}
Go程序是由包组成的,从main package的main函数开始运行。import导入包”fmt”,调用Println打印”Hello, 世界”。
1. 变量
package main
import "fmt"
var c, python, java bool // 变量由var声明,类型放在最后
var j, k int = 1, 2 // 赋初值
// error := "这种赋值语句不允许出现在函数之外"
// const Pi := 3.14 - 常量不能使用:=
const Pi = 3.14
func main() {
var i int
fmt.Println(i, c, python, java) // 变量会被默认赋初值
//: 0 false false false (//: 表示运行结果)
var c, python, java = true, false, "no!"
fmt.Println(j, k, c, python, java)
//: 1 2 true false no!
x := 3 // 自动识别变量类型
l, m, n := true, false, "no!"
fmt.Println(x, l, m, n)
//: 3 true false no!
fmt.Println(Pi)
//: 3.14
}
2. 选择
package main
import (
"fmt"
"math"
)
func sqrt(x float64) string {
if x < 0 { // 和C类似,去掉了小括号
return sqrt(-x) + "i"
}
return fmt.Sprint(math.Sqrt(x))
}
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim { // if语句内可使用:=赋值
return v
} else {
fmt.Printf("%g >= %g\n", v, lim) // else 语句
//: 27 >= 20
}
// fmt.Println(v) - 变量v的作用域仅在if语句之内
return lim
}
func main() {
fmt.Println(sqrt(2), sqrt(-4))
//: 1.4142135623730951 2i
fmt.Println(pow(3, 2, 10), pow(3, 3, 20))
//: 9 20
}
3. 循环
Go只有一种循环结构,for循环。
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ { // 与C类似,取消了小括号
sum += i
}
fmt.Println(sum)
//: 45
sum = 1
for ; sum < 1000; { // 可省略部分参数
sum += sum
}
fmt.Println(sum)
//: 1024
sum = 1
for sum < 1000 { // 实现类似while的功能
sum += sum
}
fmt.Println(sum)
//: 1024
for { // 死循环
fmt.Println("I loop forever, please use ctrl+c and exit.");
}
}
4. 函数
package main
import "fmt"
func add(x, y int) int { // 函数用func申明
return x + y
}
func swap(x, y string) (string, string) {
return y, x // 可以有多个返回值
}
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return // 根据参数列表返回相应的值,可读性差,少使用
}
func main() {
fmt.Println(add(15, 24))
//: 39
a, b := swap("hub", "zdd")
fmt.Printf("%v%v\n", a, b)
//: zddhub
fmt.Println(split(17))
//: 7 10
}
5. 基础数据类型
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // alias for uint8
rune // alias for int32
// represents a Unicode code point
float32 float64
complex64 complex128
The zero value is:
0 for numeric types,
false the boolean type, and
"" (the empty string) for strings.
The expression T(v) converts the value v to the type T: // 转换
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)
or
i := 42
f := float64(i)
u := uint(f)
6. Defer
package main
import "fmt"
func main() {
name := "zddhub"
defer fmt.Println(name) // 参数被存储,调用延后
name = "hello,"
fmt.Print(name)
//: hello,zddhub
// stacking defers
fmt.Print("counting ")
for i := 0; i < 10; i++ {
defer fmt.Print(i, " ")
}
fmt.Print(" done ")
//: hello,counting done 9 8 7 6 5 4 3 2 1 0 zddhub
}
仔细分析第18行程序输出结果,defer按照栈的顺序,先调用后执行,并保存调用时的参数。
7. 指针
package main
import "fmt"
func main() {
i, j := 42, 2701
p := &i // point to i
fmt.Println(*p) // read i through the pointer
*p = 21 // set i through the pointer
fmt.Println(i) // see the new value of i
p = &j // point to j
*p = *p / 37 // divide j through the pointer
fmt.Println(j) // see the new value of j
var a [2]string
a[0] = "hello"
a[1] = "zddhub"
pa := &a[0]
fmt.Println(*pa)
// fmt.Println(*(pa+1)) - 指针没有运算操作
}
8. 结构
Go没有class,只有struct
package main
import "fmt"
type Vertex struct { // 需要用type声明
X, Y int
}
var ( // 多行声明和赋值的写法
v1 = Vertex{1, 2} // has type Vertex
v2 = Vertex{X: 1} // Y:0 is implicit
v3 = Vertex{} // X:0 and Y:0
p = &Vertex{1, 2} // has type *Vertex
)
func main() {
fmt.Println(v1, p, v2, v3)
}
9. 内置结构
package main
import "fmt"
func main() {
var a [2]string // 数组
a[0] = "Hello"
a[1] = "World"
fmt.Println(a[0], a[1])
fmt.Println(a)
s := []int{2, 3, 5, 7, 11, 13} // Slices
fmt.Println("s ==", s)
for i := 0; i < len(s); i++ {
fmt.Printf("s[%d] == %d\n", i, s[i])
}
fmt.Println("s[1:4] ==", s[1:4])
fmt.Println("s[:3] ==", s[:3])
fmt.Println("s[4:] ==", s[4:])
// 创建Slices
c := make([]int, 5) // len(a)=5
fmt.Println(c)
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:] // len(b)=4, cap(b)=4
var z []int
fmt.Println(z, len(z), cap(z))
//: [] 0 0
if z == nil {
fmt.Println("nil!")
//: nil!
}
z = append(z, 1)
z = append(z, 2, 3, 4)
fmt.Println(z)
for i, v := range z { // range: 返回slice的index和value
fmt.Printf("z[%d] = %d\n", i, v)
}
for _, v := range z { // _, 占位符, 不使用index
fmt.Printf("%d\n", v)
}
for i := range z { // 不使用value,可以用_占位,或者只返回一个参数
fmt.Printf("%d\n", i)
}
// Maps
m := make(map[string]int)
m["hello"] = 1
m["zddhub"] = 2
fmt.Println(m["hello"], m["zddhub"])
var n = map[string]int{
"hello": 1,
"zddhub": 2, // - 需要换行时,这里的逗号不能省略
}
fmt.Println(n["hello"], n["zddhub"])
delete(n, "hello")
}
- 下一篇: Go语法简略 - 方法和接口
如果你喜欢这篇文章,欢迎赞赏作者以示鼓励