陷阱1: “is pointer to interface, not interface”

执行下面代码会出现”type *net.Conn is pointer to interface, not interface)“错误,原因是因为”net.Conn”是interface而不是struct,不能用指针方式传递。

1	func connHandler(client *net.Conn) {
2		// do something
3	}
4	
5	func somefunc() {
6		// ...
7		client, _ := listener.Accept()
8		connHandler(&client)
9	}

GO语言中interface是一种特殊的数据结构,包含两部分内容:

  1. 一个指向方法表的指针
  2. 一个指向实际数据的指针

interface

因为这种特殊的数据结构所以interface的指针指向的结构既没有实际数据也没有对应方法,那么就无法直接访问所需的内容,鉴于此原因我推测GO语言的开发者直接屏蔽掉了指向interface指针的用法。这种情况的正确如下:

1	func connHandler(client net.Conn) {
2		// do something
3	}
4	
5	func somefunc() {
6		// ...
7		client, _ := listener.Accept()
8		connHandler(client)
9	}

陷阱2: “net.ReadFromUDP 未 block导致高CPU占用”

在做UDP服务器端开发时需要用到net.ReadFromUDP()来获取客户端发送来的数据,根据这个函数定义需要传入一个’[] byte’的参数用于接收客户端数据。如果此处传入的参数是一个长度为0的slice的话就会导致CPU占满的问题。

函数定义:

func (c *UDPConn) ReadFromUDP(b []byte) (int, *UDPAddr, error)
    ReadFromUDP acts like ReadFrom but returns a UDPAddr.

问题代码:

var data []byte                               // create a slice with length of 0
n, remoteAddr, err := conn.ReadFromUDP(data)  // the call will return as soon as it's called
if err != nil {
    fmt.Println("Error read UDP:", err.Error())
}

正确代码:

var data = make([]byte, 1024)                 // make([]byte, 0, 1024) doesn't work either
n, remoteAddr, err := conn.ReadFromUDP(data)  // the call will block until there is data
if err != nil {
    fmt.Println("Error read UDP:", err.Error())
}