go语法入门

96
zhaozhengcoder
2019.05.26 14:35* 字数 260
go的基本语法
  • 数组
package main
import "fmt"

func main() {
    p := []int{2, 3, 5, 7, 11, 13}
    // 打印整个数组
    fmt.Println("p == ", p)

    // 切片
    fmt.Println("p[1:4] ==", p[1:4])

    // 省略下标代表从 0 开始
    fmt.Println("p[:3] ==", p[:3])
    fmt.Println("p[4:] ==", p[4:])

    // 使用make 创建数组
    b := make([]int, 0, 5)   // 长度len(b)=0, 容量cap(b)=5
    fmt.Println("b == ", b)
}
  • 指针
var p *int
i := 42
p = &i
fmt.Println(*p) // 通过指针 p 读取 i
*p = 21         // 通过指针 p 设置 i

指针和结构体

package main
import "fmt"

// 结构体的定义
type Vertex struct {
    X int
    Y int
}

func main() {
    fmt.Println(Vertex{1, 2})
    
    // 定义结构体
    var v Vertex
    v = Vertex{1, 2}
    fmt.Println(v)

    // 定义指针
    var pv *Vertex
    pv = &v 
    fmt.Println(*pv)
}

结构体的方法
go中结构体的方法的语法形式是:

package main

import "fmt"

type TwoInts struct {
    a int
    b int
}

func main() {
    two1 := new(TwoInts)
    two1.a = 12
    two1.b = 10

    fmt.Printf("The sum is: %d\n", two1.AddThem())
    fmt.Printf("Add them to the param: %d\n", two1.AddToParam(20))

    two2 := TwoInts{3, 4}
    fmt.Printf("The sum is: %d\n", two2.AddThem())
}

func (tn *TwoInts) AddThem() int {
    return tn.a + tn.b
}

func (tn *TwoInts) AddToParam(param int) int {
    return tn.a + tn.b + param
}

字典 map

package main

import "fmt"

func main() {

    // 创建一个字典可以使用内置函数make
    // "make(map[键类型]值类型)"
    m := make(map[string]int)

    // 使用经典的"name[key]=value"来为键设置值
    m["k1"] = 7
    m["k2"] = 13

    // 用Println输出字典,会输出所有的键值对
    fmt.Println("map:", m)

    // 获取一个键的值 "name[key]".
    v1 := m["k1"]
    fmt.Println("v1: ", v1)

    // 内置函数返回字典的元素个数
    fmt.Println("len:", len(m))

    // 内置函数delete从字典删除一个键对应的值
    delete(m, "k2")
    fmt.Println("map:", m)

    // 根据键来获取值有一个可选的返回值,这个返回值表示字典中是否
    // 存在该键,如果存在为true,返回对应值,否则为false,返回零值
    // 有的时候需要根据这个返回值来区分返回结果到底是存在的值还是零值
    // 比如字典不存在键x对应的整型值,返回零值就是0,但是恰好字典中有
    // 键y对应的值为0,这个时候需要那个可选返回值来判断是否零值。
    _, ok := m["k2"]
    fmt.Println("ok:", ok)

    // 你可以用 ":=" 同时定义和初始化一个字典
    n := map[string]int{"foo": 1, "bar": 2}
    fmt.Println("map:", n)
}

  • import 自定义的包
$ tree
.
├── foo
│   └── test.go
└── main.go

main.go

package main

import "fmt"
import "./foo"

func main() {
  bar.Abc()
  fmt.Print("This is main\n")
}

test.go

package bar

import "fmt"

func Abc() {
  fmt.Print("This is test print\n")
}
# 执行
go run main.go 

接口与反射

看了一下go的语法,感觉go接口的设计,有一点想c++的函数指针。 (上层的模块在init的时候,传递给底层的模块一个函数指针,底层模块调用的时候,根据注册的函数指针,调用不同的函数。)

channel
默认的channel是阻塞式的,如果读取一个没有数据的channel的数据,它将会被阻塞;如果向channel发送数据,它将会被阻塞,直到数据被读出来。

package main

import "fmt"
import "time"

func test_func(a int, c chan int){
    c <- a                        // 写入数据,阻塞
    fmt.Println("test_func 1 ")
    
    c <- a*2                      // 再次写入数据,又阻塞
    fmt.Println("test_func 2 ")

    fmt.Println("end")
}

func main() {
    fmt.Println("begin ~~")
    
    c := make(chan int)        
    go test_func(10, c)

    time.Sleep(3 * time.Second)    // sleep 3 second 

    fmt.Println("begin ~~~~~ ")
    x := <- c                      // 读数据,channel那端的写入操作才会继续往下执行
    fmt.Println("end : ", x)

    // main 函数结束,程序结束
}

有缓存的channel

ch := make(chan type, value)

value指定了channel里面的元素的数量。比如value=5,那么前五个元素的写入是不会阻塞的。但是,第六个元素的写入会阻塞。

  • 错误处理
  • gorouting
go入门
Gupao