golang知识备忘

原创
2020/07/01 17:07
阅读数 156

常见包

fmt

math/rand
随机数,如:rand.Intn(100) math.Sqrt() math.Pi

导入

两种方式:

import "fmt"
import "math"

或者:

import (
	"fmt"
	"math"
)

类型转换

var i int = 42
var f float64 = float64(i)
var u uint = uint(f)

循坏结构

Go只有一种循环结构:for循环。

sum := 0
for i:=0; i<10; i++{
	sum += i
}

for是Go中的while,此时你可以去掉分号,因为C的while在Go中叫做for。

sum := 1
for sum <1000 {
	sum += sum
}

无限循坏写法:

for {

}

if逻辑结构

同for一样,if语句可以在条件表达式前执行一个简单的语句。该语句声明的变量作用域仅在if和if对应的else块中使用。

if v := math.Pow(x, n); v < lim {
	return v
}
return lim

switch语句

Go的switch语句只运行选定的case,而非之后所有的case。实际上,Go自动提供了在每个case后面所需的break语句。

defer语句

defer语句会将函数推迟到外层函数返回之后执行。推迟调用的函数其参数会立即求值,但直到外层函数返回前该函数都不会被调用。

package main
import "fmt"
func main() {
	defer fmt.Println("world")
	fmt.Println("hello")
}

推迟的函数调用会被压入一个栈中,当外层函数返回时,被推迟的函数会按照后进先出的顺序调用。

结构体

一个结构体(struct)就是一组字段(filed)。

package main
import "fmt"
type Vertex struct {
	X int
	Y int
}
func main() {
	fmt.Println(Vertex{1, 2})
}

结构体字段使用点号来访问。结构体文法:

package main
import "fmt"
type Vertex struct {
	X, Y int
}
var (
	v1 = Vertex{1, 2}  // 创建一个 Vertex 类型的结构体
	v2 = Vertex{X: 1}  // Y:0 被隐式地赋予
	v3 = Vertex{}      // X:0 Y:0
	p  = &Vertex{1, 2} // 创建一个 *Vertex 类型的结构体(指针)
)
func main() {
	fmt.Println(v1, p, v2, v3)
}

数组和切片

每个数组的大小都是固定的。而切片则为数组元素提供动态大小的、灵活的视角。在实践中,切片比数组更常用。切片就像数组的引用,切片并不存储任何数据,它只是描述了底层数组中的一段,更改切片的元素会修改其底层数组中对应的元素,与它共享底层数组的切片都会观测到这些修改。

package main

import "fmt"

func main() {
	names := [4]string{
		"John",
		"Paul",
		"George",
		"Ringo",
	}
	fmt.Println(names)

	a := names[0:2]
	b := names[1:3]
	fmt.Println(a, b)

	b[0] = "XXX"
	fmt.Println(a, b)
	fmt.Println(names)
}

函数

函数也是值,它们可以像其他值一样传递。

package main

import (
	"fmt"
	"math"
)

func compute(fn func(float64, float64) float64) float64 {
	return fn(3, 4)
}

func main() {
	hypot := func(x, y float64) float64 {
		return math.Sqrt(x*x + y*y)
	}
	fmt.Println(hypot(3, 4))

	fmt.Println(compute(hypot))
	
	//fmt.Println(compute(math.Pow))
}

斐波那契闭包

package main

import "fmt"

// 返回一个“返回int的函数”
func fibonacci() func() int {
	a, b := 0, 1
	return func() int {
		temp := a
		a, b = b, a+b
		return temp
	}
}

func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}

方法

Go没有类,不过可以为结构体类型定义方法。方法就是一类带特殊的接收者参数的函数。方法接收者在它自己的参数列表内,位于func关键字和方法名之间。在此列中,Abs方法拥有一个名为v,类型为Vertex的接收者。

package main

import (
	"fmt"
	"math"
)

type Vertex struct {
	X, Y float64
}

func (v Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
	v := Vertex{3, 4}
	fmt.Println(v.Abs())
}

接口

类型通过实现一个接口的所有方法来实现该接口。既然无需专门显式声明,也就没有“implements”关键字。

package main

import "fmt"

type I interface {
	M()
}

type T struct {
	S string
}

// 此方法表示类型 T 实现了接口 I,但我们无需显式声明此事。
func (t T) M() {
	fmt.Println(t.S)
}

func main() {
	var i I = T{"hello"}
	i.M()
}
package main

import "fmt"

func main() {
	var i interface{}
	describe(i)

	i = 42
	describe(i)

	i = "hello"
	describe(i)
}

func describe(i interface{}) {
	fmt.Printf("(%v, %T)\n", i, i)
}

结构体的打印,绑定方法:

package main

import "fmt"

type Person struct {
	Name string
	Age  int
}

func (p Person) String() string {
	return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}

func main() {
	a := Person{"Arthur Dent", 42}
	z := Person{"Zaphod Beeblebrox", 9001}
	fmt.Println(a, z)
}
package main

import "fmt"

type IPAddr [4]byte

// TODO: 给 IPAddr 添加一个 "String() string" 方法
func (ip IPAddr) String() string {
	return fmt.Sprintf("%v.%v.%v.%v", ip[0], ip[1], ip[2], ip[3])
}

func main() {
	hosts := map[string]IPAddr{
		"loopback":  {127, 0, 0, 1},
		"googleDNS": {8, 8, 8, 8},
	}
	for name, ip := range hosts {
		fmt.Printf("%v: %v\n", name, ip)
	}
}
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部