Go语法

来自多彩世界 2020-07-14

创建一个map有三种方式

第一种

ages := make(map[string]int)

第二种

ages := map[string]int{
	"alice": 31,
	"charlie": 34,
}

第三种

ages := make(map[string]int)
ages["alice"] = 31
ages["charlie"] = 34

移除一个元素

delete(ages, "alice")

遍历map中所有键值对

for name, age := range ages {
	fmt.Printf("%s\t%d\n", name, age)
}

给map中的键排序

//var names []string
names := make([]string, 0, len(ages))
for name := range ages {
	names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
	fmt.Printf("%s\t%d\n", name, ages[name])
}

判断两个map是否拥有相同的键和值

func equal_map(x, y map[string]int) bool {
	if len(x) != len(y) {
		return false
	}
	for k, xv := range x {
		if yv, ok := y[k]; !ok || yv != xv {
			return false
		}
	}
	return true
}

指针

x := 1
p := &x
*p = 2

返回一个指针类型

func f() *int {
	x := 1
	return &x
}

接受一个指针类型

func incr(p *int) int {
	*p++
	return *p
}

定义一个结构体和结构体变量

type Employee struct {
	ID			int
	Name		string
	Address		string
	DoB			time.Time
	Position	string
}

var dilbert Employee

给结构体成员赋值

dilbert.ID -= 1
position := &dilbert.Position
*position = "Senior" + *position
var employeeOfTheMonth *Employee = &dilbert
employeeOfTheMonth.Position += " (proactive team player)"

赋值表达式的左侧无法识别出一个变量。

通过结构体字面量给结构体赋值

type Point struct {
	x, y int
}
p := Point{1, 2}
pp := &Point{1, 2}

结构体类型的值作为参数传递给函数或作为返回值

func Scale(p Point, factor int) Point {
	return Point{p.x * factor, p.y * factor}
}
fmt.Println(Scale(Point{1, 2}, 5))

结构体指针作为参数,效率更高

func Bonus(e *Employee, percent int) int {
	return e.ID * percent / 100
}

结构体比较

p := Point{1, 2}
q := Point{2, 1}
fmt.Println(p == q) //"false"
type address struct {
	hostname string
	port     int
}
hits := make(map[address]int)
hits[address{"golang.org", 443}]++

可比较的结构体类型都可以作为map的键类型。

结构体嵌套

type Circle struct {
	Point	//匿名成员
	Radius	int
}

type Wheel struct {
	Circle
	Spokes	int
}

var w Wheel
w.x = 8
w.y = 8
w.Radius = 5
w.Spokes = 20

w = Wheel{Circle{Point{8, 8}, 5}, 20}

w = Wheel{
	Circle: Circle{
		Point:  Point{x: 8, y: 8},
		Radius: 5,
	},
	Spokes: 20,
}

fmt.Printf("%#v\n", w)

任何命名类型或者指向命名类型的指针都可以是匿名成员。

把Go的数据结构转换为JSON称为marshal

type Movie struct {
	Title  string
	Year   int  `json:"released"`
	Color  bool `json:"color,omitempty"`
	Actors []string
}

var movies = []Movie{
	{Title: "Casablanca", Year: 1942, Color: false, 
		Actors: []string{"Humphrey", "Ingrid"}},
	{Title: "Cool Hand Luke", Year: 1967, Color: true, 
		Actors: []string{"Paul", "Newman"}},
	{Title: "Bullitt", Year: 1968, Color: true, 
		Actors: []string{"Steve", "Bisset"}},
}

data, err := json.Marshal(movies)
data2, err := json.MarshalIndent(movies, "", "    ") //格式化输出
if err != nil {
	log.Fatalf("JSON marshaling failed: %s", err)
}
fmt.Printf("%s\n%s\n", data, data2)

只有可导出的成员可以转换为JSON字段,可以通过成员标签自定义JSON字段,omitempty表示如果这个成员的值是零值或为空则不输出这个成员到JSON中。

将JSON字符串解码为Go数据结构使用Unmarshall

var titles []struct{ Title string }
if err := json.Unmarshal(data, &titles); err != nil {
	log.Fatalf("%s", err)
}
fmt.Println(titles)

函数变量

func square(n int) int { return n * n }
f := square
fmt.Println(f(3))

匿名函数


变长函数

func sum(vals ...int) int {
	total := 0
	for _, val := range vals {
		total += val
	}
	return total
}

方法声明

func (p Point) Distance(q Point) float64 {
	return math.Hypot(q.x-p.x, q.y-p.y)
}

方法是某种特定类型的函数。