

Size: a a a
> go ogle main.goК сожалению, дебаггер не был готов к релизу go1.0 и его дропнули💩
// Option AИли так:
var v T
v.Decode(someData)
Option BНа самом деле все зависит от контекста, а именно вариант В) или использование метода вместо функции - позволяет типам удовлетворять интерфейсам, т.е другими словами, если у вас есть где-то
func (t *T) Decode(data []byte) {
// decode data into *t
}
type Decoder interface{ Decode([]byte) error }
,55 . 1: *ast.IfStmt {
56 . . If: 5:2
57 . . Cond: *ast.BinaryExpr {
58 . . . X: *ast.Ident {
59 . . . . NamePos: 5:5
60 . . . . Name: "err"
61 . . . . Obj: *(obj @ 38)
62 . . . }
63 . . . OpPos: 5:9
64 . . . Op: !=
65 . . . Y: *ast.Ident {
66 . . . . NamePos: 5:12
67 . . . . Name: "nil"
68 . . . }
69 . . }
&ast.IfStmt{
Cond: &ast.BinaryExpr{
X: &ast.Ident{Name: "err"},
Op: token.NEQ,
Y: &ast.Ident{Name: "nil"},
},
}
str
или int
O_O:type runner interface {
run(context.Context, string, int)
}
2c2
< run(context.Context, string, int)
---
> run(ctx context.Context, service string, instances int)
4d3
<
type Enroller interface {
Enroll(*User, *Course) error
}
// P.S.
func main(){println("не забываем, что код пишется, еще и для наших коллеги, а не только для того, чтобы его можно было запустить на проде!")}
package mainlinks:
import (
"fmt"
)
type Person struct {
Name string
}
func (p Person) Say() {
fmt.Println("Go for two me and", p.Name)
}
func main() {
p := Person{"%username%"}
// Все варианты эквивалентны
p.Say()
Person.Say(p)
(Person).Say(p)
f1 := Person.Say; f1(p)
f2 := (Person).Say; f2(p)
}
$ git clone git@github.com:golang/go.git
$ cd go/src && ./all.bash
$ go version devel +eee07a8e68 Wed Aug 21 15:20:00 2019 +0000 darwin/amd64
package main
func main() {
println("1_200_000 -> ", 1_200_000)
println("3.1415_9265 -> ", 3.1415_9265)
println("0b0110_1101_1101_0010 -> ",0b0110_1101_1101_0010)
// println("0___ -> ", 0___) invalid example from discussion
// println(" 0__.0__e-0__ -> ",0__.0__e-0__) invalid example from discussion
// println("1__2", 1__2) invalid
}
$ go version
$ go1.12.7 darwin/amd64
$ go run main.go
# command-line-arguments
./main.go:4:28: syntax error: unexpected _200_000, expecting comma or )
./main.go:5:35: syntax error: unexpected _9265, expecting comma or )
./main.go:6:39: syntax error: unexpected b0110_1101_1101_0010, expecting comma or )
./go version
devel +eee07a8e68 Wed Aug 21 15:20:00 2019 +0000 darwin/amd64
./go run main.go
1_200_000 -> 1200000
3.1415_9265 -> +3.141593e+000
0b0110_1101_1101_0010 -> 28114
go get golang.org/dl/go1.13rc1
go1.13rc1 run main.go
1_200_000 -> 1200000
3.1415_9265 -> +3.141593e+000
0b0110_1101_1101_0010 -> 28114
$ cat main.go
package main
func g()
func f() {
for {
defer g()
}
}
func main() {
f()
}
go vet -vettool=$(which deferlint) .
# github.com/andriisoldatenko/golang_for_two
./main.go:10:4: defer in loop found "defer g()"
staticcheck
main.go:10:4: defers in this infinite loop will never run (SA5003)
staticcheck
пытается найти циклы без условий или брейков, чтобы отметить такой кейс, это помогает бороться с ложными срабатываниями.deferlint
- отличный пример, как написать свой линтер[1].defer
в анонимную функцию, чтобы гарантированно ваша отложенная функция была вызвана вовремя.func f() {
for {
func(){
defer g()
}()
}
}
defer
следует гарантированно выполнять сразу же после того, как мы освободили ресурс, который нам уже больше не нужен. А иногда - это может происходить в цикле.go doc
, для быстрого доступа к go документации, есть интересная идея как это все разукрасить:func main() {
args := []string{"doc"}
args = append(args, os.Args[1:]...)
cmd := exec.Command("go", args...)
cmd.Env = os.Environ()
output, _ := cmd.CombinedOutput()
stdout := colorable.NewColorableStdout()
err := quick.Highlight(stdout, string(output),
"go", "terminal256", style)
stdout.Write([]byte("\033[0m\n"))
}
go doc
:trollface:, как описал автор :)go get -u github.com/inancgumus/godocc
GODOCC_STYLE=monokai godocc time Unix
fmt.Printf("Num: %d %d\n", 2, 2)
// or
fmt.Printf("Num: %d %T\n", 2, 2)
fmt.Printf("Num: %d\n", 42)
fmt.Printf("Num: %d %[1]d %[1]d %[2]d %[2]d", 2, 3)
}
package mainИ мы получим в результате:😱:
import (
"fmt"
)
func main() {
const iota = iota
fmt.Println(iota, iota, iota)
}
0 0 0
.const (0 0 0
a = iota
b
c
)
fmt.Println(a, b, c)
type int struct{}Компилятор подскажет ошибку:
func main() {
var i int
i++
fmt.Println(i)
}
invalid operation: i++ (non-numeric type int)
o_OProgram:
package main
import (
"fmt"
)
var g *int
func f(p *****int) { g = ****p }
func main() {
var i int
j := &i
k := &j
l := &k
m := &l
f(&m)
fmt.Printf("%T\n", &m)
fmt.Printf("%T", f)
}
func main() {
var i = 42
var j = &i
fmt.Println("i = ", i)
fmt.Println("j = ", j)
fmt.Println("*j = ", *j)
}
// Output
i = 100
j = 0xc0000160b8
*j = 100
**p
(dereferencing a pointer to pointer).func main() {
var i = 42
var p = &i
var pp = &p
fmt.Println("pp = ", pp)
// Dereferencing a pointer to pointer
fmt.Println("*pp = ", *pp)
fmt.Println("**pp = ", **pp)
}
pp = 0xc0000bc010
*pp = 0xc0000c2000
**pp = 42
Goto Program
gotip
консольная утилита, которая помогает скомпилировать go
из мастера и очень быстро проверить, пофиксили ли баг в мастере или совместимость проекта с последней версией (origin/master).$ go get -v golang.org/dl/gotip
$ gotip download
………………………….
…. Long output…. Here…. ☕️☕️☕️
………………………….
$ gotip version
go version devel +307544f Wed Aug 28 15:49:59 2019 +0000 darwin/amd64
$ gotip run main.go
gotip
довольно простой -> https://github.com/golang/dl/blob/master/gotip/main.go#L37A
:$ cat main.go
// A is my struct
type A struct {
a bool // 1 byte
b float64 // 8 bytes
c int32 // 4 bytes
}
$ golangci-lint run --enable=maligned main.go
main.go:4:8: struct of size 24 bytes could be of size 16 bytes (maligned)
type A struct {
^
go get github.com/mdempsky/maligned
$ maligned .
/Users/andrii/work/golang_for_two/main.go:4:8: struct of size 24 could be 16
go run github.com/andriisoldatenko/proverbs
Go Proverbs, by Rob Pike
Don't communicate by sharing memory, share memory by communicating.
Concurrency is not parallelism.
Channels orchestrate; mutexes serialize.
The bigger the interface, the weaker the abstraction.
Make the zero value useful.
interface{} says nothing.
Gofmt's style is no one's favorite, yet gofmt is everyone's favorite.
A little copying is better than a little dependency.
Syscall must always be guarded with build tags.
Cgo must always be guarded with build tags.
Cgo is not Go.
With the unsafe package there are no guarantees.
Clear is better than clever.
Reflection is never clear.
Errors are values.
Don't just check errors, handle them gracefully.
Design the architecture, name the components, document the details.
Documentation is for users.
Don't panic.
package main
import (
_ "github.com/andriisoldatenko/proverbs/pkg"
)
func main() {}
func main() {
tmpDir, err := ioutil.TempDir("", "")
if err != nil {
panic(err)
}
err = createVeryLongFilePath(tmpDir)
if err != nil {
panic(err)
}
err = os.RemoveAll(tmpDir)
if err != nil {
panic(err)
}
}
os: RemoveAll fails for long file paths
Quay Security Scanner has detected 74 vulnerabilities.
Patches are available for 2 vulnerabilities.
4 High-level vulnerabilities.
clair
от CoreOS team - который умеет сканировать ваши докер имеджи на разные CVE уязвимости.clair
локально нам понадобится:docker run -p 5432:5432 -d --name db arminc/clair-db:latest
docker run -p 6060:6060 --link db:postgres -d --name clair arminc/clair-local-scan:latest
clair-scanner
локально (прочитать тут https://github.com/arminc/clair-scanner)clair-scanner -r grafana_report.txt --ip=192.168.1.200 grafana/grafana:master
2019/09/02 17:25:16 [INFO] ▶️ Start clair-scanner
2019/09/02 17:25:20 [INFO] ▶️ Server listening on port 9279
2019/09/02 17:25:20 [INFO] ▶️ Analyzing a61298a1d179786c2c176dc6c3e20c2d0cad25582e53a7bbec428fc4370a679e
...
73a18bb7d185e7c6763c97311263a8b773ce0641adb2186f7291702f4ef437bd
2019/09/02 17:25:24 [INFO] ▶️ Image [grafana/grafana:master] contains NO unapproved vulnerabilities