1 If for 后面没有小括号. 后面的花括号, 要在当前行, 并且中间有内容, 右花括号要单独一行.
因为 go 会格式化代码, 自动插入分号.
2 函数和方法的区别:
方法需要有一个接受者 (selector) 实列的函数. 这个实例必须在和方法同样的包中生命.
- funcAdd(a ,bint){
- // 函数
- fmt.Println(a+b)
- }
- func(a myInt)Add(b myInt){
- // 方法
- fmt.Println(a+b)
- }
参考文章:
3 首写是大写的字母的名称是被导出的.
4 括号后面的 int 是返回值的类型. 返回值的个数和函数中返回值的个数对应. 可以有多个返回值.
funcadd(xint,yint)int{returnx + y}
5 var 语句定义了一个变量列表.
6 := 在 go 中是简洁赋值语句, 只能用在函数内部. 函数外部, 需要用 var,func 等语句开头.
在函数中,`:=` 简洁赋值语句在明确类型的地方, 可以用于替代 var 定义.
7
Go 的基本类型有 Basic types
- bool
- string
- int int8 int16 int32 int64
- uint uint8 uint16 uint32 uint64 uintptr
- byte // uint8 的别名
- rune // int32 的别名
- // 代表一个 Unicode 码
- float32 float64
- complex64 complex128
- 8fmt.Printf("x is type of%T",x)
可以确定 x 数值的类型.
9 常量用 const 定义不能使用:= 语法定义.
10byte 为什么要 & 0xff 这样能保证符号位不变
0xff 的二进制位为 11111111
在进行 & 运算时, 高位补 0 所以, 可以保证另一个数的低 8 位不变.
参考文章:
11 math.Sqrt() 是开平方根的意思.
12math.Pow(x,n)
返回的是 x 的 n 次方.
13fmt.Printf("%g>=%g\n",v,lim)
v 和 lim 能代替前面的 %g v, 代替第一个 lim 代替第二个.
14 go 语言 牛顿法开平方:
作为练习函数和循环的简单途径, 用牛顿法实现开方函数.
在这个例子中, 牛顿法是通过选择一个初始点 z 然后重复这一过程求 Sqrt(x)的近似值:
为了做到这个, 只需要重复计算 10 次, 并且观察不同的值 (1,2,3,......) 是如何逐步逼近结果的. 然后, 修改循环条件, 使得当值停止改变 (或改变非常小) 的时候退出循环. 观察迭代次数是否变化. 结果与 [[http://golang.org/pkg/math/#Sqrt][math.Sqrt] 接近吗?
提示: 定义并初始化一个浮点值, 向其提供一个浮点语法或使用转换:
funcmain() {fmt.Println(sqrt(3))}funcsqrt(xfloat64)float64{z := xfori :=0;i <10;i++ {z = z - (z*z -x)/(2*z)}returnz}
15 switch 匹配成功会自动停止.
16 没有条件的 switch 和 switch true 一样.
17 defer 可以延迟一个函数的执行.
Defer 延迟函数的 执行顺序是后进先出.
被 defer 延迟的函数的实参(如果是方法, 还包括方法的接收者), 在 defer 语句出就会计算, 而不是等到调用时才计算.
18 go 语言有指针, 指针指向了变量的内存地址.
- var i = 10
- p := &i
& 会生成其作用对象的指针, 上面 i 的指针就赋值给了 p
- fmt.PrintLn(p)
- fmt.PrintLn(*p)
* 符号表示指针指向的底层的值, 上面的第一个答应的 p 会打印一个内存地址, 第二个 p 会答应 10
Go 语言没有指针运算.
19 struct 表示的是结构体, 表示的就是一个字段的集合.
20 结构体中的字段使用. 号来访问.
typeVertexstruct{xintystring}funcmain() {v :=Vertex{100,"56565656"}v.x =66fmt.Println(v.x)}
20 结构体的字段可以通过, 结构体的指针访问, 并且这种间接访问可以改变结构体字段的值.
21 p = Vertex{x:10} 只列出 x 的值, 没给 y 的值.
22 类型[n]T 是一个有 n 个类型为 T 的值的数组.
23 \n 是换行符.
24 []T 是一个元素类型为 T 的且切片(slice).
25s[lo:hi]
表示从 lo 到 hi-1 的元素, 包含头不包含尾. 其他的切割形式也是.
26 slice 由 make 创建会返回一个零长度的数组, 并且返回一个 slice 指向这个数组.
b := make([]int,0,5)
这个 make 定义了一个长度为 0, 空间为 5 的数组, 并且返回了这个数组的切片 b
27 数组赋值的时候, 空间大小会直接传递过去, 赋予的只是值.
28 slice 的 0 值是 nil
29 append 函数可以向 slice 添加元素.
func append(s []T, vs ...T) []T
第一参数, 是原来的 slice, 返回的是一个原来的元素添加了新元素的 slice.
30 range 可以对 slice 或 map 进行循环, 取到的第一个值是, 元素的下标, 第二个值是元素的值.
31fmt.Println(1<<uint(i) )
会返回 2,4,6,8 这样的一个二进制序列.
31 map 映射键到值.
Map 使用之前需要使用 make 而不是 new 来创建, 值为 nil 的 map 是空的, 而且不能赋值.
typeVertexstruct{Lat,Longfloat64}varmmap[string]Vertexfuncmain(){m =make(map[string]Vertex)m["bell lab"] =Vertex{Lat:100.2,Long:1559.5,}fmt.Println(m)}
上面的是 string 是键, Vertex 是值.
32 如果顶级的类型只有类型名的话, 可以在文法的元素中省略键名.
33 map[key] = value 向 map 中插入或者修改一个元素.
34 delete(map,key)删除 map 中某个元素. 这个元素被删除后, 重新取这个元素, 会显示这个元素类型的零值.
35 u,v =map[key] 第一 u, 显示的是这个元素的 值. 如果元素被删除, 则显示的是这个元素类型的 0 值. u 表示这个元素是否存在, 如果存在 u 显示为 true, 如果不存在显示为 false.
36 函数也可以当作值.
37 go 函数可以是闭包. 闭包就是, 可以读取函数内部局部变量的函数.
闭包就是能够读取其他函数内部变量的函数.
闭包使得函数中的变量一直在内存中,
- https://www.cnblogs.com/cxying93/p/6103375.html
- https://www.cnblogs.com/hzhuxin/p/9199332.html
38 斐波那契数列 : 从第三项开始, 之后的每一项都是前两项的和.
斐波那契数列 (Fibonacci sequence), 又称黄金分割数列, 因数学家列昂纳多. 斐波那契(Leonardoda Fibonacci) 以兔子繁殖为例子而引入, 故又称为 "兔子数列", 指的是这样一个数列: 1,1,2,3,5,8,13,21,34,...... 在数学上, 斐波那契数列以如下被以递推的方法定义: F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)在现代物理, 准晶体结构, 化学等领域, 斐波纳契数列都有直接的应用, 为此, 美国数学会从 1963 年起出版了以《斐波纳契数列季刊》为名的一份数学杂志, 用于专门刊载这方面的研究成果.
packagemainimport"fmt"funcfibonacci()func()int{x :=0y :=1return func()int{z := x + yx,y = y,zreturnz}}funcmain(){f :=fibonacci()fori :=0;i <10;i++ {fmt.Println(f())}}
39 go 语言没有类, 不过仍然可以在结构体类型上定义方法.
方法的接收者, 放在 func 和方法名之间.
40 type 可以定义函数类型, 结构体类型, 接口类型, 定义等价类型(相当于类型重命名).
type 在 switch 中还可以进行类型查询.
https://www.cnblogs.com/craneboos/p/8615476.html
41 可以对任意类型定义方法, 而不仅仅针对结构体.
42 接口是一组方法的集合.
只要 这个方法的 fucname result arguement 和接口中的方法一直, 就认为, 这个方法实现了接口.
结构体是, 实现方法的接收者.
43 类型通过实现接口的方法, 实现接口. 这样实现了接口和类型之间的解耦.
44returnfmt.Sprintf("%d.%d.%d.%d",i[0],i[1],i[2],i[3])
可以返回格式化之后的字符串.
45returnfmt.Sprintf("cannot Sqrt negative number:%v",float64(e))
上面这行, 代码使用 %v 可以实现值的替换, 可是使用 %d 没办法实现值的替换. 看了下源码, 没看完
46io 包指定了 io.Reader 接口, 它表示从数据流结尾读取.
func (T) Read(b []byte) (n int, err error)
Read 用数据填充指定的字节 slice, 并且返回填充的字节数, 和错误信息.
在遇到数据的结尾时, io.eof 错误.
47 golang 如何判断变量的类型
funcmain(){v:='A'fmt.Println(reflect.TypeOf(v))}
48 fmt.pringLn fmt.Fprint fmt.Sprintf 的各种用法:
fmt.Fprint 格式化, 并输出到 io.writer
49web 服务器
包 http 通过任何实现了 http.Handler 的值, 相应 HTTP 请求.
50 goroutine 是 go 运行时环境的轻量级线程.
go f(x,y,z) 开启了一个新的 goroutine 执行 f(x,y,z)
X,y,z 是在当前线程中定义的, 不过在新的 goroutine 中执行他们.
51 channal 是有类型的管道, 在正常情况下, 在另一端装备好之前, 发送和接受都会被阻塞, 可以帮助 goroutine 实现同步.
Channal 可以使用 <- 操作符, 来发送或者接收变量.
Ch <- v
于 map 和 slice 一样, channel 必须使用 make 创建.
Ch := make(chan int)
52 channel 可以带缓冲区, make 第二个参数作为一个缓冲区, 来初始化一个 channel.
M:= make(chan int, 10)
向 channel 发送数据的时候, 如果缓冲区已满, 则会发生阻塞. 如果缓冲区已空, 从 channel 中取数据则会发生阻塞.
53 发送者, 可以把 channel 关闭. 向一个已经关闭的 channel 发送值会引发 pannic.Channel 和文件不同, 通常情况下不需要关闭他们, 只有在告诉接受这没有更多数据的时候, 才有必要进行关闭, 例如中断一个 range
K,ok := <-c 当 channel 已经没有值, 并且已经被关闭的是偶, 第二个 ok 会被赋值为 false.
54 go 的 select 语句会监听 io 操作, 当 io 操作发生时, 触发相应的操作.
在执行 Select 语句的时候, 运行系统会自动的自上而下的判断每个 case 中发送或者接收操作可以被立即执行.(立即执行的意思是, 当前 goroutine 不会因操作而阻塞).
如果有一个或者多个 io 操作可以执行, select 会随机选择一个, 否则, 如果有 defualt 则执行 defualt, 如果 defualt 都没有则, select 会一直等待.
参考文章:
来源: http://www.bubuko.com/infodetail-3345009.html