Go语言学习

变量和函数

函数编写
func add(x int, y int) int {
	return x + y
}
// 也可以写成这样 func add(x, y int) int{}
// 函数可以返回任意数量的返回值
func swap(x, y string) (string, string) {
	return y, x
}

变量声明
var flag1, flag bool
var i int
// 声明的时候进行初始化
var i, str int, string = 1, "abc"
// 如果初始化值存在,那么可以省略类型,系统可以自动从初始值中获得类型,比如:
var i, str = 1, "abc"
// 在函数内可以用:=代替var进行声明
i, str := 1, "abc"
常量声明
const world = "世界"
类型转换
// 需要显式转换
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)

流程控制语句

for语句
for i:=0; i<10; i++ {
	fmt.Println(i)
}
while语句
sum := 0
for i<10 {
	sum += i
}
if语句
if i < 10 {
	fmt.Println(i)
}
// 同 for 一样, if 语句可以在条件表达式前执行一个简单的语句。该语句声明的变量作用域仅在 if 之内。
// 在 if 的简短语句中声明的变量同样可以在任何对应的 else 块中使用。
func judge(a, b, c float64) float64 {
	if var := math.Pow(a, b); var < c {
		return c
	}
}
switch语句
// 每条case语句自带break
// switch语句也可以不带条件,就等同于if-else语句
func main() {
	fmt.Print("Go runs on ")
	switch os := runtime.GOOS; os {
	case "darwin":
		fmt.Println("OS X.")
	case "linux":
		fmt.Println("Linux.")
	default:
		fmt.Printf("%s.\n", os)
	}
}
defer语句
func main() {
	defer fmt.Println("world")
	fmt.Println("hello")
}
// 被defer的语句会被压入一个栈中,之后执行按照出栈顺序执行
func main() {
	fmt.Println("counting")

	for i := 0; i < 10; i++ {
		defer fmt.Println(i)
	}

	fmt.Println("down")
}
/* 执行结果
counting
down
9 8 7 6 5 4 3 2 1 0
*/

struct slice和映射

指针
func main() {
	i, j := 42, 2701

	p := &i         // 指向 i
	fmt.Println(*p) // 通过指针读取 i 的值
	*p = 21         // 通过指针设置 i 的值
	fmt.Println(i)  // 查看 i 的值 i的值为21

	p = &j         // 指向 j
	*p = *p / 37   // 通过指针对 j 进行除法运算
	fmt.Println(j) // 查看 j 的值
}
结构体
type Vertex struct {
	X int
	Y int
}

func main() {
	v := Vertex{1, 2}
	v.X = 4
	v1 := Vertex{X:1} // Y缺省
	fmt.Println(v.X)
}

// 结构体指针
func main() {
	v := Vertex{1, 2}
	p := &v
	p.X = 1e9 // 这里可以省略(*p).X
	fmt.Println(v)
}
数组
func main() {
	// 声明方式1
	var a [2]string
	a[0] = "Hello"
	a[1] = "World"
	// 声明方式2
	primes := [6]int{2, 3, 5, 7, 11, 13}
}
切片
func main() {
	primes := [6]int{2, 3, 5, 7, 11, 13}
	// 或者写成这样 primes := []int{2, 3, 5, 7, 11, 13}
	// 声明方式1
	var s []int = primes[1:4]
	// 声明方式2
	p := primes[1:4]
	fmt.Println(s)
}
// 更改切片的元素会修改其底层数组中对应的元素。
// var a [10]int 则a[0:10] a[:10] a[0:] a[:]是等价的

// 切片有长度和容量,长度指的是切片中元素的个数,容量是指从切片中第一个元素到底层数组最后一个元素的个数
s := []int{2, 3, 5, 7, 11, 13}
s = s[:0]	// len(s)=0 cap(s)=6 s=[]
s = s[:4]	// len(s)=4 cap(s)=6 s=[2357]
s1 = s[2:]	// len(s)=2 cap(s)=4 s1=[57]
s2 = s[2:6]	// len(s)=4 cap(s)=4 s2=[571113] 从切片s的第三个元素开始数4个

// 切片的零值是 nil。nil 切片的长度和容量为 0 且没有底层数组。

// 用make创建动态数组
a := make([]int, 5)	// len(a) = cap(a) = 5
b := make([]int, 0, 5)	// len(b)=0 cap(b)=5

// 二维切片
board := [][]string{
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
	}
board[0][0] = "x"

// 用append给切片添加元素,如果添加之后元素的个数大于底层数组的容量,会自动增加底层数组的容量
var a []int
a.append(a, 1)
a.append(a, 2, 3, 4)

// range遍历切片,返回的第一个值是数组下标,第二个是元素
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

func main() {
	for i, v := range pow {
		fmt.Printf("2**%d = %d\n", i, v)
	}
}
// 如果只想要索引
for i := range pow
// 如果只想要值
for _, v := range pow
映射
type Vertex struct {
	Lat, Long float64
}

var m = map[string]Vertex{
	"Bell Labs": Vertex{40.68433, -74.39967},
	"Google":    Vertex{37.42202, -122.08408},
}

// 推荐以下方式
m := make(map[string]int)
m["anny"] = 1
m["belta"] = 2
// 删除
delete(m, "anny")
v, ok := m["anny"] // 返回的是0, false
v, ok := m["belta"] // 返回的是2, true
函数闭包
// 一个函数返回另一个函数 另一个函数和函数体外的某个变量联系在一起 相当于递归
func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x
		return sum
	}
}

func main() {
	pos, neg := adder(), adder()
	for i := 0; i < 10; i++ {
		fmt.Println(pos(i))
	}
}

// 实现斐波那契
// 实际上就是把递归中循环用到的值通过函数体外变量的方式记录下来
func fibonacci() func() int {
	pre1 := 0
	pre2 := 1
	return func() int {
		temp := pre1
		pre1 = pre2
		pre2 = temp + pre2
		return temp
	}
}

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

方法和接口

为结构体定义方法
type Vertex struct {
	X, Y float64
}
// 调用方法时为v.Abs()
func (v Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
指针接受者和值接受值
// 值接受者 调用函数之后不会改变v的值
func (v Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
// 指针接受者 调用函数之后会改变v的值
/* 
该方法被调用时 接受者既可以为值也可以为指针
var v Vertex
v.Scale(5)  // OK
p := &v
p.Scale(10) // OK
*/
func (v *Vertex) Scale(f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}
// 改写的函数
/*
该方法被调用时 接受者只能为指针
var v Vertex
ScaleFunc(v, 5)  // 编译错误!
ScaleFunc(&v, 5) // OK
*/
func ScaleFunc(v *Vertex, f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}
接口
type Animal interface {
	eat()
}

type Cat struct {
	name string
}
func (cat Cat) eat() {
	fmt.Println("fish")
}

type Dog struct {
	name string
}
func (dog Dog) eat() {
	fmt.Println("meat")
}

func main() {
	var I Animal = Cat("miao")
	I.eat()
}

// 空接口 用来处理未知类型的值 
var i interface{}
// 下面是一个例子
func do(i interface{}) {
	switch v := i.(type) {
	case int:
		fmt.Printf("Twice %v is %v\n", v, v*2)
	case string:
		fmt.Printf("%q is %v bytes long\n", v, len(v))
	default:
		fmt.Printf("I don't know about type %T!\n", v)
	}
}

func main() {
	do(21)
	do("hello")
	do(true)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值