📜 ⬆️ ⬇️

If you are thinking of starting to write on Go, this is what you should know.

Your favorite pet writes on Go and gets more than you, but you are not there yet? Do not waste time ... Such a thought could be born to the reader from the abundance of articles on Go. Some even offer companies to retrain in this language. And, if you ever thought to master a language, then I want to warn you. Rather, show the strange things, try to explain why they are and then you will make your own conclusion whether you need Go.

Go is a portable C


Who is this article for?


The article is primarily intended for those people for whom the expressiveness of the language is important. And at the same time for those who want to touch Go.
I myself am a C ++ / Python developer and I can say that this combination is one of the best for mastering Go. And that's why:
')


What about the Java / C # pair? Go to her is never a competitor, at least as long as he is young (talking about the Go 1.11 version).

What will not be in the article




What will happen? Only specific cases of discomfort that the language delivers in the work.

Beginning of work


A good introduction to the language manual is a short online book Introduction to Go programming . Reading that you rather quickly stumble upon strange features. First, we will give the first batch of them:

Odd compiler


Only Egyptian brackets are supported.
Only Egyptian brackets are supported, that is, the following code does not compile:
package main

func main()  //  
{

}

, . — .

a := []string{
	"q"  //  ,  
}

-, . , , .

? !
, .
package main

func main() {
	a := []string{
		"q",
	}
	//  ,   
}


, , , , . , . , . .
, . - .

, :
for _, value := range x {
    total += value
}



. .

«»


. , , .

:
« , (..: ) . , , , , Java, C/C++, Python. , , . .»

: Go .

?
var x map[string]int
x["key"] = 10

:
panic: runtime error: assignment to entry in nil map


«» . , ?
tyderh , :
, , , . , .


:
  var i32 int32 = 0
  var i64 int64 = 0
  
  if i64 == i32 {
    
  }

, . Go (!) , , :
package main

import (
	"fmt"
)

func eq(val1 interface{}, val2 interface{}) bool {
	return val1 == val2
}

func main() {
	var i32 int32 = 0
	var i64 int64 = 0
	var in int = 0

	fmt.Println(eq(i32, i64))
	fmt.Println(eq(i32, in))
	fmt.Println(eq(in, i64))
}

, . false, , . , .

powerman :
func returnsError(t bool) error {
	var p *MyError = nil
	if t {
		p = ErrBad
	}
	return p // Will always return a non-nil error.
}
err := returnsError(false)
if err != nil {
  # 
}

nil nil, . FAQ .

. , ( ) . :
package main

import "fmt"

type storage struct {
	name string
}

var m map[string]storage

func main() {
	m = make(map[string]storage)
	m["pen"] = storage{name: "pen"}

	if data, ok := m["pen"]; ok {
		data.name = "-deleted-"
	}

	fmt.Println(m["pen"].name) // Output: pen
}

pen. :
package main

import "fmt"

type storage struct {
	name string
}

var m map[string]*storage

func main() {
	m = make(map[string]*storage)
	m["pen"] = &storage{name: "pen"}

	if data, ok := m["pen"]; ok {
		data.name = "-deleted-"
	}

	fmt.Println(m["pen"].name) // Output: -deleted-
}

"-deleted-", , , , «» .
?
:
m = make(map[string]storage)
:
m = make(map[string]*storage)


, ? , :
package main

import "fmt"

var globState string = "initial"

func getState() (string, bool) {
	return "working", true
}

func ini() {
	globState, ok := getState()
	if !ok {
		fmt.Println(globState)
	}
}

func main() {
	ini()
	fmt.Println("Current state: ", globState)
}

initial := . - ok. ,
globState, ok := getState()
globState = getState()

, IDE , , .

, PVS Go.

: , .


«»


, , . , . .
, :
make([]int, 50, 100)
new([100]int)[0:50]

, , new, . .

, :
var i int = 3
j := 6

, , var .

, Go .

«»


, :
result, err := function()
if err != nil {
    // ...
}

Go, . Go . result, err := function(), result, err = function(). , . — := = , .

«»


Go, , , , . .

- «», . 2018 Go 2.0, , . , «» .

. in not in. map :
if _, ok := elements["Un"]; ok {
}

— , , .


Go . . . SQL JOIN ORM GO (gorm) :
db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&results)

ORM :
query := models.DB.LeftJoin("roles", "roles.id=user_roles.role_id").
  LeftJoin("users u", "u.id=user_roles.user_id").
  Where(`roles.name like ?`, name).Paginate(page, perpage)

ORM . .

:
a.GET("/users/{name}", func (c buffalo.Context) error {
  return c.Render(200, r.String(c.Param("name")))
})

- , .



, ? : . : , . . « » ( , ).


, - :
elements := map[string]map[string]string{
		"H": map[string]string{
			"name":  "Hydrogen",
			"state": "gas",
		},
        }

, ? - , . :
elements := map[string](map[string]string){
        }

, go fmt, . .


. . « » .
helgihabr , 1.9 sync.Map.


. Go , :
if result != 1 {
    t.Fatalf("result is not %v", 1)
    }

, , assert . : https://github.com/vizor-games/golang-unittest.

:
assert.NotEqual(t, result, 1, "invalid result")



. , «» . , . .
-:
string([]byte{'a'})

, :
y.(io.Reader)

. .
conversion, . static_cast ++.
type assertion . dynamic_cast ++.



vgo , JetBrains GoLand 2018.2, IDE :
vgo mod -vendor

, , . go2 .
1.11 . .


, Go, . , .



Go . : , . , ( RTTI) , .
, , .







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


All Articles