This is a translation of username tucnak with Medium, which received an extensive discussion at reddit.com/r/programming .

Okay, the title is really somewhat loud, I admit. C say more: I prush from loud headlines, all because of attention. In this blog post I will try to prove the fact that Go is an awfully thoughtful language (spoiler: it is). I've been playing with Go for several months now, the first helloworld gathered, it seems, in June. No mathematician out of me, but since then something has passed for about 4 months and I even managed to
upload several repositories on
Github and collect some stars! It is also worth mentioning that I have absolutely no experience of using Go in production, so any of my words about “supporting the code” or “deployed” should not be taken as the only true truth.
I love Go, I loved it the first time I tried it. I spent a few days trying to accept the idioms, come to terms with the lack of generics, deal with the frankly strange way of error handling, and you know, with all these classic problems one way or another connected with Go. I read
Effective Go , many articles from the
blog of Dave Cheney, followed all the news from the world of Go. I can even say that I am quite an active member of the community! I love Go and can't do anything about it - Go is just wonderful. However, I believe that Go is a terrible, badly thought-out language that does not at all what it “sells”.
Go is considered a simple programming language. As Rob Pike
said , they “removed everything that could be removed from the language,” which made its specification simply trivial. This side of the language is simply amazing: you can learn the basics in minutes, immediately start writing real code and in most cases Go will behave exactly as you expect. You will be a lot of rage, but fortunately, everything will work cool. In reality, everything is a little different, Go is far from being a simple language, rather just a bad one. Now look at a few of the arguments that confirm my words.
')
Reason number 1. Manipulations with slices are just disgusting.
Slice (these are heaped-up arrays) are very cool, I really like the concept and direct implementation. But let's imagine for a moment that some time we will want to write with them a bit of source code, maybe quite a bit. Slices are the heart of the language, this is one of those concepts that makes Go cool. But nevertheless, let's imagine that somehow all of a sudden, in the intervals between talking about “concepts”, we would like to write a bit of real code. Here is what Go offers us in this case:
// ...
numbers := []int{1, 2, 3, 4, 5}
log(numbers) // 1. [1 2 3 4 5]
log(numbers[2:]) // 2. [3 4 5]
log(numbers[1:3]) // 3. [2 3]
// : !
//
// numbers[:-1] Python .
// - :
//
log(numbers[:len(numbers)-1]) // 4. [1 2 3 4]
// “” , ! !
//
// :
//
numbers = append(numbers, 6)
log(numbers) // 5. [1 2 3 4 5 6]
// :
//
numbers = append(numbers[:2], numbers[3:]...)
log(numbers) // 6. [1 2 4 5 6]
// - ? ,
// Go best practice!
//
// ...
//
numbers = append(numbers[:2], append([]int{3}, numbers[2:]...)...)
log(numbers) // 7. [1 2 3 4 5 6]
// , :
//
copiedNumbers := make([]int, len(numbers))
copy(copiedNumbers, numbers)
log(copiedNumbers) // 8. [1 2 3 4 5 6]
// .
, — , . ,
insert(), . a
playground, : .
â„–2. :)
, « Go , » , . ,
spf13 Docker
«7 common mistakes in Go and when to avoid them».
, error (, , ). , . ,
, , ?
package main
import "fmt"
type MagicError struct{}
func (MagicError) Error() string {
return "[Magic]"
}
func Generate() *MagicError {
return nil
}
func Test() error {
return Generate()
}
func main() {
if Test() != nil {
fmt.Println("Hello, Mr. Pike!")
}
}
, , , Go. , .
. , Go ,
, - ;)
â„–3.
, , -
: “ , ( , , ) , ”. , , . , Go , : :=, .
Go:
package main
import "fmt"
func Secret() (int, error) {
return 42, nil
}
func main() {
number := 0
fmt.Println("before", number) // 0
{
// meet the shadowing
number, err := Secret()
if err != nil {
panic(err)
}
fmt.Println("inside", number) // 42
}
fmt.Println("after", number) // 0
}
, , := , . . , ( ) , («after 42»). , ? .
, , , , . Go . , , , .
â„–4. []struct []interface
, Pike&Co. , , Go: , , Go . , «Effective Go» . , « », , , ,
Go . , ( ) , :
package main
import (
"fmt"
"strconv"
)
type FancyInt int
func (x FancyInt) String() string {
return strconv.Itoa(int(x))
}
type FancyRune rune
func (x FancyRune) String() string {
return string(x)
}
// String().
type Stringy interface {
String() string
}
// , .
func Join(items []Stringy) (joined string) {
for _, item := range items {
joined += item.String()
}
return
}
func main() {
numbers := []FancyInt{1, 2, 3, 4, 5}
runes := []FancyRune{'a', 'b', 'c'}
// !
//
// fmt.Println(Join(numbers))
// fmt.Println(Join(runes))
//
// prog.go:40: cannot use numbers (type []FancyInt) as type []Stringy in argument to Join
// prog.go:41: cannot use runes (type []FancyRune) as type []Stringy in argument to Join
//
// :
//
properNumbers := make([]Stringy, len(numbers))
for i, number := range numbers {
properNumbers[i] = number
}
properRunes := make([]Stringy, len(runes))
for i, r := range runes {
properRunes[i] = r
}
fmt.Println(Join(properNumbers))
fmt.Println(Join(properRunes))
}
, , - .
Go, ?
Wiki , , []struct []interface . , ! , , . , , . Go ? -, , ?
, , « , ». . , Go .
№5. « »
UPD: , . , , .. , ., - Go. , «for-range» , . . , , :
range- « », — foreach ++.
package main
import "fmt"
func main() {
numbers := []int{0, 1, 2, 3, 4}
for _, number := range numbers {
number++
}
fmt.Println(numbers) // [0 1 2 3 4]
for i, _ := range numbers {
numbers[i]++
}
fmt.Println(numbers) // [1 2 3 4 5]
}
, , Go range- « », , range- . “range” “ ”, “ ”.
For “Effective Go”, , range- , . , , ( ), , , . , “Effective Go”.
â„–6.
, Go , . , unused import. ? , . , , unused import , . , - , , - ? , ?
Go1.5
: - . Go team , , .
, Go — . , Go (import / var / const):
import (
"fmt"
"math"
"github.com/some_guy/fancy"
)
const (
One int = iota
Two
Three
)
var (
VarName int = 35
)
, «», , . - , , . , , :
numbers := []Object{
Object{"bla bla", 42}
Object("hahauha", 69}
}
:
numbers := []Object{
Object{"bla bla", 42},
Object("hahauha", 69},
}
, import / var / const . ,
, . !
â„–7. Go
-, . , Go, , , . , go:generate — Go, , . , , , . , . , , - , . , - ! , :
func Blabla() {
// code...
}
//go:generate toolname -params -blabla
// code...
, . , Go. , , ,
. , , unused imports, .
, / / , Go. , , , , . , , ! « » , , , « » .
, Go. : . : , , , , .
, , Go?