banner

Go的一些基础知识笔记

分类: Go |发布时间: 10/26/2017, |修改时间: 11/29/2018, |共有 0 条评论 点此返回

需要更新一个满足自己的Blog。选用Go作为服务器后端开发语言。

来历

2002年3月由Google发布, 跟C语言很像。

语言特性

  • 静态强类型
  • 编译型
  • 并发型
  • 垃圾回收

关键字

根据关键字回忆这些都是干什么的。


break default func interface select
case defer go map struct
chan else goto package switch
const if range type
continue for import return var

一些笔记

defer作用

  • 在程序return执行前, 添加的defer语句按照逆序执行。
  • defer语句是后进先出(LIFO)的。

import 各种操作

保留字main和init, 不需要调用, 在import时候自动调用。main只能在main包中存在。

/*可以省略包的前缀名调用函数*/
import(
. "fmt"
)
/*alias*/
import(
f "fmt"
)
/*只执行该包中的init函数, 不直接使用包中的函数*/
import(
_ "github.com/zzz/sss"
)

面向对象

A method is a function with an implicit first argument, called a receiver.

使用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())
}

如果一个method的receiver是指针, 那么你可以不需要加&, Go自动知道使用地址。

interface

可以接受任何实现该interface类型的对象!
必须由其他非interface类型实现, 不能自我实现
如果一个东西实现了interface中的所有方法, 那么可以被interface持有
空interface可以存储任何值(var a interface{})

反向 - 知道interface持有的是哪个变量

  • comma-ok sentence: value, ok = element.(T)
  • element.(type) in switch

Reflect

  1. Reflection goes from interface value to reflection object.
  2. Reflection goes from reflection object to interface value.
  3. To modify a reflection object, the value must be settable
    • v.CanSet()
    • a copy of original value is not settability, we must use &

并发

  • 使用go关键字, 现在可以根据runtime.GOMAXPROCS(n)告诉调度器同时使用多个线程。
  • channels: chan关键字, 必须使用make来创建, 定义发送类型。
  • 默认是阻塞的, 收发的时候将会等待直到有数据接收或发出, 但是也可以设定buffer, 大于buffer size才阻塞。
  • close() 要在生产者关闭channel, 而不是消费的地方去关闭。
  • channe不需要经常去关闭
  • 使用select可以监听某个channel上的数据流动, 用法比较像switch

ch := make(chan int) // create a channel of type int
ch <- 42 // Send a value to the channel ch.
v := <-ch // Receive a value from ch

// Non-buffered channels block. Read blocks when no value is available, write blocks if a value already has been written but not read.

// Create a buffered channel. Writing to a buffered channels does not block if less than <buffer size> unread values have been written.
ch := make(chan int, 100)

close(ch) // closes the channel (only sender should close)

// read from channel and test if it has been closed
v, ok := <-ch

// if ok is false, channel has been closed

// Read from channel until it is closed
for i := range ch {
fmt.Println(i)
}

// Test

// select blocks on multiple channel operations, if one unblocks, the corresponding case is executed
func doStuff(channelOut, channelIn chan int) {
select {
case channelOut <- 42:
fmt.Println("We could write to channelOut!")
case x := <- channelIn:
fmt.Println("We could read from channelIn")
case <-time.After(time.Second * 1):
fmt.Println("timeout")
}
}

0 条评论

评论排序
banner

Tokei

Entertainment & Technical Blog

Bilibili |  Github