Язык программирования GO

Preview:

DESCRIPTION

Артем Первухин "Язык программирования GO" В докладе будет рассказано, чем сможет заинтересовать Python-разработчика язык программирования Go. Будут описаны базовые идиомы языка Go и даны ответы на следующие вопросы: Насколько применим к Go "Zen of Python"? Какая у этого языка область применения? В чём можно выиграть, использовав Go вместо Python?

Citation preview

Язык программирования Goдля программистов на Python30.05.2014

Артём Первухин

Почему Go?

статическая типизация

один файл на выходе

конкурентность и масштабируемость

Немного истории

сентябрь 2007: идейное рождение (Robert Griesemer, Rob Pike, Ken Thompson)

осень 2009: open source

март 2012: Go 1.0

июнь 2014: Go 1.3

What's in the box?

golang.org (http://golang.org) , дистрибутив Go 1.3 beta2 ~ 50 Мб

компилятор

стандартная библиотека

документация

всё для кросс-компиляции (amd64, i368, arm, *BSD, Linux, OS X, Windows)

инструменты

Некоторые команды

godoc — документация в консоли или локальная копия golang.org

go build — компиляция

go install — компиляция и установка

go run — компиляция и запуск отдельного файла

go test — тесты, бенчмарки

go fmt — получить красивый код

go get — скачать по сети пакет, скомпилировать и установить

Пакеты

Установка пакета:

go#get#github.com/artyom/ru

Системы контроля версий: git, mercurial, bazaar, subversion

package#main

import#(

####"fmt"

####"github.com/artyom/ru"

)

func#main()#{

####num#:=#42

####fmt.Println(num,#ru.Pluralize(num,#"питонов",#"питон",#"питона"))

} Run

Пакеты — размещение на диске

Разные $GOPATH — аналоги разных virtualenv:

$GOPATH

####bin/

########doPsomethingPfun

####pkg/

########darwin_amd64/

############github.com/

################user/

####################coolstaff.a

####src/

########github.com/

############user/

################coolstaff/

####################common.go

####################items.go

####################smth.go

####################smth_test.go

####################doPsomethingPfun/

########################code.go

Don't communicate by sharing memory, share memory by communicating

Горутины + каналы = concurrency

func#worker(n,#delay#int,#res#chan#string)#{

####fmt.Println("worker",#n,#"started")

####time.Sleep(time.Duration(delay)#*#time.Second)

####res$<&$fmt.Sprintf("result$from$worker$%d",$n)####fmt.Println("hi#from#worker",#n)

}

func#main()#{

####results$:=$make(chan$string)####for#i#:=#1;#i#<#4;#i++#{

########go#worker(i,#i+1,#results)

####}

####fmt.Println("waiting#for#all#workers")

####for#i#:=#1;#i#<#4;#i++#{

########item$:=$<&results########fmt.Println(item)

####}

} Run

Обработка последовательностей

Python:

list comprehensions

map, reduce, filter

Go:

for

for#...#range

####seasons#:=#[]string{"зима",#"весна",#"лето",#"осень"}

####for#i,#s#:=#range#seasons#{

########fmt.Println(i,#s)

####} Run

Обработка последовательностей

#!/usr/bin/env#python

move_month#=#lambda#y,m,x:#[((yP1,12),(y,m))[bool(m)]#for#y,m#in#[divmod(y*12+m+x,12)]][0]

print#move_month(2013,#11,#+1)

print#move_month(2013,#12,#+1)

print#move_month(2014,#1,#P1) Run

Обработка последовательностей

Объектно-ориентированность

Структуры и методы

type#Person#struct#{

####Name#######string

####Occupation#string

}

Методы — просто функции с получателем:

func#(p#Person)#Title()#string#{

####return#strings.Title(p.Name#+#",#"#+#p.Occupation)

}

(и никакого self!)

Методы и структуры

type#Person#struct#{

####Name#######string

####Occupation#string

}

func#(p#Person)#Update(o#string)#{

####p.Occupation#=#o

}

func#main()#{

####ivan#:=#Person{

########Name:#######"Иван#Васильевич#Бунша",

########Occupation:#"управдом",

####}

####fmt.Println(ivan.Title())

####ivan.Update("великий$князь")

####fmt.Println(ivan.Title())

} Run

Наследование?

Встраивание!

type#Parent#struct#{

####Name####string

####Surname#string

}

type#Child#struct#{

####Name###string

####Parent}

func#main()#{

####p#:=#Parent{"Sarah",#"Connor"}

####c$:=$Child{"John",$p}####fmt.Println(c.Name,#c.Surname)

####c.Surname#=#"Doe"

####fmt.Println(c.Name,#c.Surname)

} Run

If it walks like a duck...

Интерфейсы

Python, PEP 3119, Introducing Abstract Base Classes:

...the ABCs define a minimal set of methods that establish the characteristic behavior of the type. Codethat discriminates objects based on their ABC type can trust that those methods will always bepresent.

Интерфейсы

Go: интерфейсы — типы-обобщения, определяющие только набор методов.

//#Reader#is#the#interface#that#wraps#the#basic#Read#method.

type#Reader#interface#{

####Read(p#[]byte)#(n#int,#err#error)

}

//#Writer#is#the#interface#that#wraps#the#basic#Write#method.

type#Writer#interface#{

####Write(p#[]byte)#(n#int,#err#error)

}

Интерфейсы + встраивание типов = комбинирование:

//#ReadWriter#is#the#interface#that#groups#the#basic#Read#and#Write#methods.

type#ReadWriter#interface#{

####Reader

####Writer

}

Почти что декораторы

def#memo(function):

####m#=#dict()

####def#wrapper(n):

########if#n#in#m:

############return#m[n]

########value#=#function(n)

########m[n]#=#value

########return#value

####return#wrapper

@memo

def#heavy(n):

####print("doing#complex#calculations")

####time.sleep(0.5)

####return#n+n

if#__name__#==#"__main__":

####print(heavy(1))

####print(heavy(2))

####print(heavy(1))

####print(heavy(2)) Run

Почти что декораторы

func#memo(f#func(int)#int)#func(int)#int#{

####m#:=#make(map[int]int)

####return#func(n#int)#int#{

########if#value,#ok#:=#m[n];#ok#{

############return#value

########}

########value#:=#f(n)

########m[n]#=#value

########return#value

####}

}

Почти что декораторы

(продолжение)

(Привет, Python 2.3!)

func#heavy(n#int)#int#{

####fmt.Println("doing#complex#calculations")

####time.Sleep(500#*#time.Millisecond)

####return#n#+#n

}

var$cached$=$memo(heavy)

func#main()#{

####fmt.Println(cached(1))

####fmt.Println(cached(2))

####fmt.Println(cached(1))

####fmt.Println(cached(2))

} Run

*args, **kwargs

Variadic functions

func#Foo(prefix#string,#values#...int)#string

func(string,#[]int)#string

Примеры вызова:

Foo("pref1")

Foo("pref2",#1)

Foo("pref3",#1,#2)

values#:=#[]int{1,2,3,4,5}

Foo("pref4",#values...)

Ошибки

file,#err#:=#os.Open("file.go")

if#err#!=#nil#{

####log.Fatal("failed#to#open#file",#err)

}

По типу функции явным образом понятно, может ли она вернуть ошибку:

func#Open(name#string)#(file#*File,#err#error)

defer — отложи на потом

Python, менеджеры контекста:

with#open("filename.txt",#"r")#as#inFile:

######do#something#with#file

with#conn:

####conn.execute("insert#into#person(firstname)#values#(?)",#("Joe",))

Go, defer — откладывание исполнения функций «на потом»:

f,#err#:=#os.Open("filename.txt")

if#err#!=#nil#{

####log.Fatal("failed#to#open#file",#err)

}

defer#f.Close()

...

Документация

Документация в виде комментариев перед кодом:

//#Println#formats#using#the#default#formats#for#its#operands#and#writes#to#standard#output.

//#Spaces#are#always#added#between#operands#and#a#newline#is#appended.

//#It#returns#the#number#of#bytes#written#and#any#write#error#encountered.

func#Println(a#...interface{})#(n#int,#err#error)#{

####return#Fprintln(os.Stdout,#a...)

}

Чтение из консоли:

$#godoc#fmt#Println

func#Println(a#...interface{})#(n#int,#err#error)

####Println#formats#using#the#default#formats#for#its#operands#and#writes#to

####standard#output.#Spaces#are#always#added#between#operands#and#a#newline

####is#appended.#It#returns#the#number#of#bytes#written#and#any#write#error

####encountered.

☞ godoc#Psrc#... покажет и код

Документация

В html на сайте:

Документация

godoc.org (http://godoc.org) — документация на публично доступные пакеты.

Batteries included

Стандартная библиотека

Стандартная библиотека

Несколько примеров:

strings

regexp

flag

database/sql

encoding/*, особенно encoding/json и encoding/xml

net, net/http

os/* и path/*

text/template и html/template

testing

Стандартная библиотека: html/template

O'Reilly:#How#are#<i>you</i>?

Контекстно-зависимое автоматическое экранирование:

Context##########################{{.}}#After

{{.}}############################O'Reilly:#How#are#&lt;i&gt;you&lt;/i&gt;?

<a#title='{{.}}'>################O&#39;Reilly:#How#are#you?

<a#href="/{{.}}">################O&#39;Reilly:#How#are#%3ci%3eyou%3c/i%3e?

<a#href="?q={{.}}">##############O&#39;Reilly%3a%20How%20are%3ci%3e...%3f

<a#onx='f("{{.}}")'>#############O\x27Reilly:#How#are#\x3ci\x3eyou...?

<a#onx='f({{.}})'>###############"O\x27Reilly:#How#are#\x3ci\x3eyou...?"

<a#onx='pattern#=#/{{.}}/;'>#####O\x27Reilly:#How#are#\x3ci\x3eyou...\x3f

Стандартная библиотека: testing

$#ls#P1#*_test.go

bench_test.go

decode_test.go

encode_test.go

example_test.go

fold_test.go

scanner_test.go

stream_test.go

tagkey_test.go

tags_test.go

Тесты:

func#TestMyFunction(t#*testing.T)#{

####res#:=#MyFunction(1,#2)

####if#res#!=#3#{

########t.Fatal("expecting#3,#got",#res)

####}

}

Стандартная библиотека: testing

$#go#test#

PASS

ok######encoding/json####1.975s

$#go#test#Pcover

PASS

coverage:#89.6%#of#statements

ok######encoding/json####1.990s

$#go#test#Pbench#.

PASS

BenchmarkCodeEncoder#########100######26941238#ns/op######72.03#MB/s

BenchmarkCodeMarshal#########100######25133822#ns/op######77.21#MB/s

BenchmarkCodeDecoder##########20######87467936#ns/op######22.18#MB/s

BenchmarkCodeUnmarshal##########20######87582700#ns/op######22.16#MB/s

BenchmarkCodeUnmarshalReuse##########20######82352420#ns/op

BenchmarkUnmarshalString#####2000000###########776#ns/op

BenchmarkUnmarshalFloat64#####5000000###########584#ns/op

BenchmarkUnmarshalInt64#####5000000###########509#ns/op

BenchmarkSkipValue##########50######21558521#ns/op######90.21#MB/s

BenchmarkEncoderEncode#####2000000###########876#ns/op#########219#B/op###########2#allocs/op

ok######encoding/json####26.096s

Zen of... Go?

The#Zen#of#Python,#by#Tim#Peters

Beautiful#is#better#than#ugly.

Explicit#is#better#than#implicit.

Simple#is#better#than#complex.

Complex#is#better#than#complicated.

Flat#is#better#than#nested.

Sparse#is#better#than#dense.

Readability#counts.

Special#cases#aren't#special#enough#to#break#the#rules.

Although#practicality#beats#purity.

Errors#should#never#pass#silently.

Unless#explicitly#silenced.

In#the#face#of#ambiguity,#refuse#the#temptation#to#guess.

There#should#be#onePP#and#preferably#only#one#PPobvious#way#to#do#it.

Although#that#way#may#not#be#obvious#at#first#unless#you're#Dutch.

Now#is#better#than#never.

Although#never#is#often#better#than#*right*#now.

If#the#implementation#is#hard#to#explain,#it's#a#bad#idea.

If#the#implementation#is#easy#to#explain,#it#may#be#a#good#idea.

Namespaces#are#one#honking#great#idea#PP#let's#do#more#of#those!

Ресурсы

golang.org (http://golang.org)

blog.golang.org (http://blog.golang.org)

play.golang.org (http://play.golang.org)

gobyexample.com (https://gobyexample.com)

gophercon.com (http://gophercon.com)

Twitter:

Rob Pike @rob_pike (https://twitter.com/rob_pike)

Brad Fitzpatrick @bradfitz (https://twitter.com/bradfitz)

Andrew Gerrand @enneff (https://twitter.com/enneff)

Russ Cox @_rsc (https://twitter.com/_rsc)

Дмитрий Вьюков @dvyukov (https://twitter.com/dvyukov)

Thank you

Артём Первухин

artyom@evasive.ru (mailto:artyom@evasive.ru)

https://evasive.ru (https://evasive.ru)

Recommended