const var = 1
const (
var = 1
)
[]rune
,unicode
切片(rune是int32的别名)可使用 ` 和 ” 创建
双引号创建可解析字符串,支持转义序列,不支持多行
反引号创建原生字符串,不支持转义序列,支持多行,可包含除了反引号之外的任意字符
可使用 for range循环
for idx, rune range str {
....
}
[]byte
,所以 []byte(string) string([]byte)
只需要O(1),无需复制string[idx]
索引字符;而对于包含非ASCII字符的字符串,需要转换成[]rune(string)
再索引strings.IndexFunc(string, indexFunc)
可使用自定义方法查询index,如unicode.IsSpace
来查询任意空白符的位置strings.FieldsFunc(string, func(rune) bool)
遍历string中rune,如果匿名函数返回true则进行拆分type test struct {
id int64
}
hello := new(test)
hello.id = 2
Go语言的 . 操作符,会直接解引用指针,无需再显示使用 * 解引用
[length]Type
[N]Type{value1, value2, ...}
[...]Type{value1, value2, ...}
make([]Type, length, capacity)
make([]Type, length)
[]Type{}
[]Type{value1, value2, ...}
for _, amount := range amounts {
amount = amount * 2
}
正确修改方式如下
for i := range amounts {
amounts[i] xxxxx
}
append(slice1, slice2[idx:]...)
make(map[KeyType] ValueType, initialCapacity)
make(map[KeyType] ValueType)
map[KeyType] ValueType{}
map[KeyType] ValueType{key1: value1, ...}
value, bFound := map[key]
delete(map, key)
:=
,如果声明的变量已经存在了,只有当声明语句位于块作用域的起始处,才会新创建一个变量,否则会直接覆盖原值。resultOfType := Type(expression)
resultofType, bOK := expression.(Type)
resultofType := expression.(Type)
,如果失败,panicif optionalStatement; booleanExpression {
} else if optionalStatement; booleanExpression {
} else {
}
fallthrough
关键字switch optionalStatement; optionalExpression {
case optionalStatement; booleanExpression: blockStatements
case optionalStatement; booleanExpression: fallthrough
default: blockStatements
}
typeSwitchGuard
是一个结果为类型的表达式。如果 对开关表达式使用了 快速申明,那么获取的值为开关表达式中的变量的值,类型决定于case分支switch optionalStatement; typeSwitchGuard {
case typeLis1: block
...
default: block
}
for {//无限循环
block
}
for booleanExpression {// while循环
block
}
for optionalPreStatement; booleanExpression; optionalPostStatement {// 普通for循环
block
}
for index, value := range string or array or slice {// 普通for range循环,字符串、数组、切片
block
}
for index := range string or array or slice {// 省略value的for range循环,字符串、数组、切片
block
}
for key, value := range map {// 普通for range循环,映射
block
}
for item := range channel{// 通道迭代
block
}
go functionName(arguments) // 调用已有函数
go func(parameters){block}(arguments) // 创建新匿名函数
make(chan Type)
make(chan Type, capacity)
通道默认是双向的
不声明缓冲区容量的通道默认为同步的,阻塞直至发送准备好发送或者接收准备好接收
给定缓冲区容量则认为是异步的,只要缓冲区存在未使用空间或者包含可接收数据,就会是异步的
channel <- value //阻塞发送
<- channel // 接收并丢弃
x := <- channel // 接收并保存
x, ok := <- channel // 接收并保存并判断通道是否已关闭或者是否为空
延时关闭可使用defer关键字
defer func(){ // defer函数会在外层函数返回时被调用
close(chanVar)
}
close关键字不支持关闭 只接收的通道
select会评估所有case语句中的通道操作是否阻塞,全部阻塞时,若无default则等待,若有default执行default后继续执行后续语句;通道操作有可执行的,则执行并进入对应block,然后执行后续语句
select {
case sendOrRecv1: block
case sendOrRecv2: block
default: block
}
func functionName(optionalParameters) optionalReturnType {
}
func functionName(optionalParameters) (optionalReturnValues){
}
有返回值的函数一定需要return(或者结尾处存在panic)。如果返回值未命名,则须在return后紧跟返回值类型定义相同的返回值;如果返回值已命名,则return后可空白
可变参数函数,这里...Type
实际上是[]Type
切片
func functionName(values ...Type){// 其实, ...的作用是展开切片的意思。 numbers[1:]... 代表展开 numbers切片的子切片
}
interface{}
来作为参数类型自定义结构体与添加的方法,首字母大写的会被导出,小写的不 导出
type ColoredPoint struct{
color.Color // 嵌入
x, y int // 聚合
}
自定义类型,typeSpecification可以是内置类型、接口、结构体、函数签名 type typeName typeSpecification
添加方法,就是在定义函数时指明了所属,函数名称要求在所属对象中唯一
type Count int
func (count *Count) Increment() {*count++}
func (count *Count) Decrement() {*count--}
func (count Count) IsZero() {return count == 0}
type Item struct {
id string
price float64
quantity int
}
func (ite *Item) Cost() float64 {
return item.price * float64(item.quantity)
}
type LuxuryItem struct {
Item // 嵌入成员
cataogId int
markup int
}
func (item* LuxuryItem ) cost (item *Luxuryitem) float64 {
return item.Item.Cost * item.markup
}
asStringV := Part.String
sv := asStringV(part)
lowerP := (*Part).LowerCase
lowerP(&part)
type Exchanger interface {
Exchange()
}
type StringPair struct {
first, second string
}
func (stringPair *StringPair) Exchange() {
stringPair.first, stringPair.second = stringPair.second, stringPair.first
}
type PointPair [2]int
func (pointPair *PointPair) Exchange() {
pointPair[0], pointPair[1] = pointPair[1], pointPair[0]
}
func BatchExchange(pairs ...Exchanger) {
for _, pair := range pairs {
pair.Exchange()
}
}
func TestExchangeInterface() {
stringpair := StringPair{"1", "2"}
pointpair := PointPair{1, 2}
fmt.Println("Before ", stringpair, pointpair)
BatchExchange(&stringpair, &pointpair)
fmt.Println("After ", stringpair, pointpair)
}
type LowerCase interface {
ToLowerCase()
}
type UpperCase interface {
ToUpperCase()
}
type LowerUpperCase interface {
LowerCase
UpperCase
}
type Person struct {
Title string
Forenames []string
Surname string
}
type Author1 struct {
Names Person // 聚合
Title []string
YearBorn int
}
type Author2 struct {
Person // 嵌入,匿名结构体字段
Title []string
YearBorn int
}
func Test_embedAndAggregation() {
author1 := Author1{Person{"Person", []string{"X", "U"}, "ZHE"}, []string{"XU", "ZHE"}, 19911115}
author1.Names.Title = "Male" // 聚合结构体的字段访问
fmt.Println(author1)
author2 := Author2{Person{"Person", []string{"M", "A"}, "ZHUOJUN"}, []string{"MA", "ZHUO", "JUN"}, 19920227}
author2.Surname = "ZHUOJUN2"// 聚合结构体的字段访问,不存在冲突
author2.Person.Title = "Female"// 聚合结构体的字段访问,存在冲突
fmt.Println(author2)
}
aStruct{field1:value1}
runtime.NumCPU()
返回当前机器的逻辑处理器或者核心数量rumtime.GOMAXPROCS(n)
n为0时,同上。n > 0时,设置Go运行时系统可以使用的处理器数sync库支持如下
waiter := &sync.WaitGroup() // 创建
go func() {
// 然后再某个routine中
waiter.Add(1)
// 该routine结束的时候
waiter.Done()
}()
// 如果要等待这一组通过Add方法收集的routine的结束
waiter.Wait()
也叫 类型检视(introspection)
reflect.DeepEqual()
可用于比较== != 不能比较的对象reflect.valueOf()
返回一个reflect.Value
结构,可以通过它获取真实值、获取成员、调用方法等relect.Value.Elem()
,获取值,替换掉指针所指向的string值。如下test := "test1"
value := reflect.ValueOf(&test)
value.Elem().SetString("test2")
reflect.Value.Call([]reflect.Value) []reflect.Value
可以调用当前Value对应的方法。reflect.TypeOf(interface{}).Kind()
可以获取类型,如reflect.Array, reflect.Chan等reflect.Value.MethodByName(string) reflect.Value
可以获取指定方法