【go学习笔记】tour.go - 基础部分

导出名

任何以大写字母开头的变量或函数,都将在go中导出名称(exported names)。只有导出的函数和变量可以从其他包中访问。

Printf和Println的区别:

Printf : 只可以打印出格式化的字符串,可以输出字符串类型的变量,不可以输出整形变量和整形
Println :可以打印出字符串,和变量

:=的用法

只要:=左边有一个新变量都可以用:=,否则只能用=

命名返回值

可以在函数顶部定义待返回的变量名称,return优先级高

变量的初始化

变量声明可以包含初始值,每个变量对应一个。如果初始化值已存在,则可以省略类型;变量会从初始值中获得类型。
①可以定义类型,但不显式设置初始值

var a int

②可以设置初值,但不显式定义类型

var a = 1

③同时定义类型并初始化

var a int = 1

等同于在类型明确的地方用:=代替var进行声明

a := 1
b, c = "go",true

但这只能在函数体中使用

基本类型

变量声明也可以“分组”成一个语法块。
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // uint8 的别名
rune // int32 的别名
// 表示一个 Unicode 码点
float32 float64
complex64 complex128

for

for 是 Go 中的 “while”

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

if

同 for 一样, if 语句可以在条件表达式前执行一个简单的语句。

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

等价于

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

用牛顿法实现平方根函数

func Sqrt(x float64) float64 {
	z1 := 1.0
	z2 := z1 - ((z1*z1 - x) / (2*z1))
	cnt := 1
	for z1-z2>0.000001||z2-z1>0.000001{
		z1 = z2
		z2 -= (z1*z1 - x) / (2*z1)
		cnt++
	}
	fmt.Println(cnt)
	return z2
}

switch

Go 自动提供了每个 case 后面所需的 break 语句,除非以 fallthrough 语句结束,否则分支会自动终止。 Go 的另一点重要的不同在于 switch 的 case 无需为常量,且取值不必为整数。
没有条件的 switch 同 switch true 一样,这种形式能将一长串 if-then-else 写得更加清晰。

结构体

type Vertex struct {
	X int
	Y int
}

切片

切片为数组元素提供动态大小,比数组更为常用。更改切片的元素会修改其底层数组中对应的元素。

primes := [6]int{2, 3, 5, 7, 11, 13}
var s []int = primes[2:4]

结果输出:[5 7]
或另一种定义方式:

s := []int{2, 3, 5, 7, 11, 13}

结构体切片:

s := []struct {
		i int
		b bool
	}{
		{2, true},
		{3, false},
		{5, true},
		{7, true},
		{11, false},
		{13, true},
	}

切片的长度就是它所包含的元素个数。len(s)

切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。cap(s)
(起始默认是前一个切片,长度按照当前的计算,不切尾)

var s []int

这样的切片s == nil
还可以用make创建切片

b := make([]int, 0, 5) // len(b)=0, cap(b)=5

(len为0,所以b[1]不存在,但是可以c := b[:2],然后对c[1]进行修改)
二维切片

board := [][]string{
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
}

Range

for 循环的 range 形式可遍历切片或映射。在循环遍历切片时,每次迭代都会返回两个值。第一个值为当前元素的下标,第二个值为该下标所对应元素的一份副本。

切片练习

func Pic(dx, dy int) [][]uint8 {
	res := make([][]uint8,dy)
	for i := 0;i<dy;i++{
		for j := 0;j < dx;j++{
			res[i] = append(res[i],(uint8)(i*j))
		}
	}
	return res
}

映射

type Vertex struct {
	Lat, Long float64//其中是
}
func main() {
	m := make(map[string]Vertex)
	m["Bell Labs"] = Vertex{
		40.68433, -74.39967,
	}
	fmt.Println(m["Bell Labs"])
}
n := make(map[string]int)
n["num"] = 32
fmt.Println(n["num"])

这个make 函数会返回给定类型的映射,并将其初始化备用。不能像下面这样调用:

b := make([]int)
b[0] = 15
fmt.Println(b[0])

映射的文法与结构体相似

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

若顶级类型只是一个类型名(Vertex),你可以在文法的元素中省略它。

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

删除元素:

delete(m, key)

通过双赋值检测某个键是否存在:

elem, ok = m[key]

映射练习

func WordCount(s string) map[string]int {
	m := make(map[string]int)
	ss := strings.Fields(s)
	for i := 0;i<len(ss);i++{
		m[ss[i]]++
	}
	return m
}

函数值

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

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(5, 12))

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

函数的闭包

func adder() func(int) int {
	sum := 0
	return func(x int) int {//匿名函数
		sum += x
		return sum
	}
}

func main() {
	pos, neg := adder(), adder()//相当于pos是前面return func这里的func名
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),
			neg(-2*i),
		)
	}
}

斐波纳契闭包

package main

import "fmt"

// 返回一个“返回int的函数”


func fibonacci() func() int {
	num := 0
	pre := 0
	return func() int{
		if num == 0{
			num = 1
		}else{
			tmp := num
			num = num+pre
			pre =tmp
		}
		return pre
	}
}

func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值