gopath
- src 存放源代码(比如:.go .c .h .s等)
- pkg 编译后生成的文件(比如:.a)
- bin 编译后生成的可执行文件
go类型
rune, int8, int16, int32, int64和byte, uint8, uint16, uint32, uint64。其中rune是int32的别称,byte是uint8的别称,浮点数的类型有float32和float64两种(没有float类型),默认是float64。
Go还支持复数,它的默认类型是complex128(64位实数+64位虚数)。如果需要小一些的,也有complex64(32位实数+32位虚数)。复数的形式为RE + IMi,其中RE是实数部分,IM是虚数部分,而最后的i是虚数单位。
var c complex64 = 5+5i
//output: (5+5i)
fmt.Printf("Value is: %v", c)
array、slice、map
- array就是数组,数组也就不能改变长度
- slice并不是真正意义上的动态数组,而是一个引用类型。slice总是指向一个底层array,slice的声明也可以像array一样,只是不需要长度。
make、new
- 内建函数make(T, args)与new(T)有着不同的功能,make只能创建slice、map和channel,并且返回一个有初始值(非零)的T类型,而不是*T。本质来讲,导致这三个类型有所不同的原因是指向数据结构的引用在使用前必须被初始化。例如,一个slice,是一个包含指向数据(内部array)的指针、长度和容量的三项描述符;在这些项目被初始化之前,slice为nil。对于slice、map和channel来说,make初始化了内部的数据结构,填充适当的值。
- new(T)分配了零值填充的T类型的内存空间,并且返回其地址,即一个*T类型的值。用Go的术语说,它返回了一个指针,指向新分配的类型T的零值。
switch
Go里面switch默认相当于每个case最后带有break,匹配成功后不会自动向下执行其他case,而是跳出整个switch, 但是可以使用fallthrough强制执行后面的case代码。
integer := 6
switch integer {
case 4:
fmt.Println("The integer was <= 4")
fallthrough
case 5:
fmt.Println("The integer was <= 5")
fallthrough
case 6:
fmt.Println("The integer was <= 6")
fallthrough
case 7:
fmt.Println("The integer was <= 7")
fallthrough
case 8:
fmt.Println("The integer was <= 8")
fallthrough
default:
fmt.Println("default case")
}
函数
import
- 相对路径
import “./model” //当前文件同一目录的model目录,但是不建议这种方式来import
- 绝对路径
import “shorturl/model” //加载gopath/src/shorturl/model模块
- 点操作
import(
. "fmt"
)
fmt.Println("hello world")可以省略的写成Println("hello world")
import(
f "fmt"
)
import (
"database/sql"
_ "github.com/ziutek/mymysql/godrv"
)
_操作其实是引入该包,而不直接使用包里面的函数,而是调用了该包里面的init函数。
struct匿名字段
type Human struct {
name string
age int
weight int
}
type Student struct {
Human // 匿名字段,那么默认Student就包含了Human的所有字段
speciality string
}
通过匿名访问和修改字段相当的有用,但是不仅仅是struct字段,所有的内置类型和自定义类型都是可以作为匿名字段的。如果字段名有冲突遵循最外层的优先访问原则,访问内层的可以通过匿名字段名来访问
面向对象-method
method语法定义
func (r ReceiverType) funcName(parameters) (results)
在使用method的时候重要注意几点:
- 虽然method的名字一模一样,但是如果接收者不一样,那么method就不一样
- method里面可以访问接收者的字段
- 调用method通过.访问,就像struct里面访问字段一样
- receiver既可以是值传递,也可以是引用传递
- 可以用在你自定义的类型、内置类型、struct等各种类型上面
- 如果一个method的receiver是*T,你可以在一个T类型的实例变量V上面调用这个method,而不需要&V去调用这个method
- 如果一个method的receiver是T,你可以在一个*T类型的变量P上面调用这个method,而不需要 *P去调用这个method
- 如果匿名字段实现了一个method,那么包含这个匿名字段的struct也能调用该method。
package main
import (
"fmt"
"math"
)
type Rectangle struct {
width, height float64
}
type Circle struct {
radius float64
}
func (r Rectangle) area() float64 {
return r.width*r.height
}
func (c Circle) area() float64 {
return c.radius * c.radius * math.Pi
}
func main() {
r1 := Rectangle{12, 2}
r2 := Rectangle{9, 4}
c1 := Circle{10}
c2 := Circle{25}
fmt.Println("Area of r1 is: ", r1.area())
fmt.Println("Area of r2 is: ", r2.area())
fmt.Println("Area of c1 is: ", c1.area())
fmt.Println("Area of c2 is: ", c2.area())
}
可见性
Go语言没有像其它语言一样有public、protected、private等访问控制修饰符,它是通过字母大小写来控制可见性的,如果定义的常量、变量、类型、接口、结构、函数等的名称是大写字母开头表示能被其它包访问或调用(相当于public),非大写开头就只能在包内使用(相当于private,变量或常量也可以下划线开头)