golang 知识点

前端之家收集整理的这篇文章主要介绍了golang 知识点前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1.//.(type),比如 username.(string)

&:类型断言,是interface{}转string

2..//判断网页中checkBox是否被选中

&:为checkBox添加value属性,后台判断r.FormValue(checkBox的name属性) != "",表示被选中

3.//直接输出HTML

string类型go的template处理时会自动做escape处理,用template.HTML类型就不会了

values := map[string]template.HTML{"html": template.HTML("<br/>")}

4.//slice赋值

var a = []string{
	"1","2",}

func Do() (c []string) {
       b := a
       log.Print(len(b),cap(b))//2,2  len = cap 了,append后将创建新的底层数组
       b = append(b,"3")
       log.Print(len(b),cap(b))
       log.Print(b,a)
       return b
}

func Do1() (c []string) {
	b := a //这是引用,b,a指向同一个底层array
	log.Print(b,a)
	b[1] = "3" //a同时变化
	log.Print(b,a)
	return b
}
//slice赋值
func Do2() (c []string) {
	c = make([]string,2) //要先声明否则下面赋值时会越界
	copy(c,a)
	log.Print(c,a)
	c[1] = "2"
	log.Print(c,a)
	return c
}

slice具体使用可参考http://blog.golang.org/go-slices-usage-and-internals

//select问题

问题1:

messages := make(chan string)
signals := make(chan bool)
select {
case msg := <-messages:
fmt.Println("received message",msg)
default:
fmt.Println("no message received")
}
msg := "hi"
select {
case messages <- msg:
fmt.Println("sent message",msg)
default:
fmt.Println("no message sent")
}
select {
case msg := <-messages:
fmt.Println("received message",msg)
case sig := <-signals:
fmt.Println("received signal",sig)
default:
fmt.Println("no activity")
}
不是应该输出:
no message received
sent messagehi
received messagehi
怎么会是:
no message received
no message sent
no activity

原因:

默认通道是 无缓冲 的,这意味着只有在对应的接收(<- chan)通道准备好接收时,才允许进行发送(chan <-),即非缓冲通道,没有接收者会阻塞.你可能会问第一个select不是给第二个select提供接受者了吗?其实:

第一个 select 里面的 case msg := <-messages 虽然尝试执行,但是由于当时 messages 里面没有数据,所以最后执行的是 default,也就是<- 操作就没有执行,messages 又没有 buffer,所以第二个 select 执行的时候已经没有 goroutine 在接受 messages 里面的数据了,自然没法 send 数据。

第一个 select 可以来理解为:

if messages has data to be read {
msg := <- messages
// execute code after the case statement
} else {
// default
}
当然,上面的代码第一行和第二行是原子的执行的。如果messages当时没有数据,又可以不 block,那么就相当于messages什么也没变化。

ps:

channel的receiver和sender需在两个不同的goroutine里,否则会应为阻塞,出现deadlock.

问题2:

ch := make(chan int,1)
for {
select {
case ch <- 0:
case ch <- 1:
}
i := <-ch
fmt.Println("value=",i)
}
程序怎么会交替随机输出0和1呢?

原因是golang select机制(https://golang.org/ref/spec#Select_statements):

检查每个case语句
如果有任意一个chan是send or recv read,那么就执行该block
如果多个case是ready的,那么随机找1个并执行该block
如果都没有ready,那么就block and wait
如果有default block,而且其他的case都没有ready,就执行该default block

问答3:

package main
import "fmt"

func main() {
jobs := make(chan int,5)
done := make(chan bool)

go func() {
for {
j,more := <-jobs
if more {
fmt.Println("received job",j)
} else {
fmt.Println("received all jobs")
done <- true
return
}
}
}()

for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent job",j)
}
close(jobs)
fmt.Println("sent all jobs")

<-done
}

关闭的channel仍可读取?channel特性:一个已经被关闭的 channel 永远都不会阻塞,但不能再向这个 channel 发送数据,不过仍然可以尝试从 channel 中获取值,直至读完剩余数据,而后才开始返回对应channel类型的零值.

参考:绝妙的 channel#http://blog.csdn.net/kjfcpua/article/details/18263839

//timer

<-timer.C 是直到这个定时器Stop()之前,将一直阻塞,除非timer时间到期接收到了新的数据(Time),即timer过期.

//syscall.Exec 参数疑问

syscall.Exec(binary,args,env)中的args其实只用到了args[1:],即args[0]会被忽略

//url encode

url.QueryEscape("我爱golang")

//无缓冲channel,先要有读否则写阻塞

N:=time.Duration(0) //尝试修改N的值,看结果
messages := make(chan string)


go func() { messages <- "ping"
println(1)}()

time.Sleep(N*time.Second)
msg := <-messages
fmt.Println(msg)

获取上传文件大小:

下面的大小文件是针对存放数据的缓冲区而言.


// 获取文件大小的接口,for 小文件保存在内存中
type Size interface {
    Size() int64
}
// 获取文件信息的接口,for 大文件,在虚拟内存中
type Stat interface {
    Stat() (os.FileInfo,error)
}
if statInterface,ok := file.(Stat); ok {
    fileInfo,_ := statInterface.Stat()
    fmt.Fprintf(w,"上传文件的大小为: %d",fileInfo.Size())
}
if sizeInterface,ok := file.(Size); ok {
    fmt.Fprintf(w,sizeInterface.Size())
}

//new

new(T)会为T类型分配内存,其值为零值,并且返回它的地址;想同时初始化可用&T.

猜你在找的Go相关文章