📜 ⬆️ ⬇️

Translation: One year with Go

Under the cut - the translation of the article by an experienced developer about his experience of practical use of Go. Important - the opinion of the translator may not coincide with the opinion of the author of the article.




So, a year has passed since I started using Go. A week ago I deleted it from production.
')
I’m writing this post because over the past year, many have asked me about my impressions of working with Go, and I would like to talk about it a little more than is possible on Twitter and IRC - until the memories fade from my mind.

So, let's talk about why I don't think Go is a useful tool:

Tools


The tools that come with Go are weird. At first glance, many of them are not bad, but after long work, most of them begin to demonstrate their limitations. Compared with tools for C or Erlang, they look like a not very good joke.

coverage analysis


Strictly speaking, the Go code analysis utility is a hack. It only works with one file at a time and does this by pasting code like this:

GoCover.Count[n] = 1

n — . :

var GoCover = struct {
        Count     [7]uint32
        Pos       [3 * 7]uint32
        NumStmt   [7]uint16
} {
        Pos: [3 * 7]uint32{
                3, 4, 0xc0019, // [0]
                16, 16, 0x160005, // [1]
                5, 6, 0x1a0005, // [2]
                7, 8, 0x160005, // [3]
                9, 10, 0x170005, // [4]
                11, 12, 0x150005, // [5]
                13, 14, 0x160005, // [6]
        },
        NumStmt: [7]uint16{
                1, // 0
                1, // 1
                1, // 2
                1, // 3
                1, // 4
                1, // 5
                1, // 6
        },
}


, — . , . , .


— , . . « » ( 1 ), . , . benchmark.go:

func (b *B) nsPerOp() int64 {
    if b.N <= 0 {
        return 0
    }
    return b.duration.Nanoseconds() / int64(b.N)
}

, , .

go vet


Go — . , , , — go vet. printf, go vet. , : 1.3 , 1.2.

go get


go get, , .

$GOPATH


, . , . $GOPATH , , .

Go race detector


— . . , (FreeBSD, -?) goroutine 8192. , race condition — , race detector .


Channels/mutexes


. production , daemontools .


go , goroutine stdout. . , , ‘evacuation not done in time’ ‘freelist empty’. google, .

runtime



, Go « ». gdb, .


Go. interface{} . , . C , ?

, Go ( C ). , , . , ?

byte[] string /. , , .

[:],... append. :

iv = append(iv, truncatedIv[:]...)

, append , . , realloc.


, , OpenSSL, . … , « X».

'net'. , . IP_RECVPKTINFO? 'syscall', POSIX , . , 'syscall':

fd, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_DGRAM, 0)
if err != nil {
    rlog.Fatal("failed to create socket", err.Error())
}
rlog.Debug("socket fd is %d\n", fd)

err = syscall.SetsockoptInt(fd, syscall.IPPROTO_IPV6, syscall.IPV6_RECVPKTINFO, 1)
if err != nil {
    rlog.Fatal("unable to set IPV6_RECVPKTINFO", err.Error())
}

err = syscall.SetsockoptInt(fd, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 1)
if err != nil {
    rlog.Fatal("unable to set IPV6_V6ONLY", err.Error())
}

addr := new(syscall.SockaddrInet6)
addr.Port = UDPPort

rlog.Notice("UDP listen port is %d", addr.Port)

err = syscall.Bind(fd, addr)
if err != nil {
    rlog.Fatal("bind error ", err.Error())
}


, byte[] 'syscall' . C Go — - .

, polling ? , .


Go. , C/D/Rust. , Erlang Haskell. Go, — , . , «» . , Ruby/Python/Java , , , Go. , Go « Java», . Ruby/Python/Java, , Go — . . LISP « », «C» , Ruby , Erlang , Haskell , Rust . , -, Go.

Source: https://habr.com/ru/post/268411/


All Articles