Язык программирования go для perl-программистов
DESCRIPTION
Введение в язык программирования Go с интересными примерами.TRANSCRIPT
Язык Go для Perl-программистов
— Зачем знать про Go?— Откуда про него узнать?— Зачем нужен Go?
Почему Goна Perl-мероприятии?
Кругозор
Тренды
XXI век
Дух перла (совсем немного)
Дух перла (совсем немного)
душок :-)
UTF-8всегда и везде
UTF-8всегда и везде
Даже в именах переменных
UTF-8всегда и везде
Даже в именах переменных
Perl 6!
return a, b
return a, b
Perl!
golang.org
Написан на Go
tour.golang.org
Есть офлайновая версия
goprogrammingbook.com
Март 2012
Локальный golang.org
$ godoc -‐http=:6060
The Go programming language is an open source project to make programmers more productive.
«
»
Perl is a general-purpose programming language originally developed for text manipulation
«
»
Go is expressive, concise, clean, and efficient.
«»
The language is intended to be practical <. . .> rather than beautiful
«»
Go — компилируемый
язык
Go — быстрокомпилируемый
язык
C-подобный синтаксис
Скорость компиляцииопределяет синтаксис
Встроенный сборщик мусора
Ни на что не похожие интерфейсы
Нет ООП и наследования
В начале 2012обещают
GO 1.0
В GO 1.0 зафиксируют синтаксис
Не все старые программы работают в новых релизах Go
Не все старые программы работают в новых релизах Go
Perl 6!
— Синтаксис— Интерфейсы
Синтаксис
01-‐hello.goaddr_in_noninit.goarray.goassign-‐new.goblank.gochannel.goclose_channel.gocomplex.gocopy-‐array.godb.godefer-‐func.godefer.godial.goecho.goeven-‐use.goeven.gofactorial.gofmt.gogoroutine.goimport_.goinit.goint_method.go
interface.gointerface_vars.goiota.goiota_print-‐1.goiota_print-‐2.goiota_print.golen.gomap.gomap_autovivif.gomap_non_existent.gomul_int64.goopenfile.gopanic.gopointer.gopp.goprintln.goq10.goq11.goq12.goq12a.goq2-‐2.goq2-‐3.go
q3.goq4-‐2.goq4-‐4.goq4.goq6.goq7.goq9.gorandom-‐select.gorange-‐string.gorange.goreceiver.gorecover.goreslice.gosort-‐delay-‐1.gosort-‐delay.gosort.gostring_range.gostruct.goswitch.gotype-‐struct.govar.govariadic.go
Hello, World!
package main
import "fmt"
func main() { fmt.Println("Hello, World!")}
Многабукаф?
class HelloWorld { static public void main(String args[]) { System.out.println( "Hello, World!" ); }}
Java
#include<iostream>
int main() { std::cout << "Hello, World!\n"; return 0;}
C++
package main
import "fmt"
func main() { fmt.Println("Hello, World!")}
Go
package main
import "fmt"
func main() { fmt.Println("Hello, World!")}
;
package main
import "fmt"
func main() { fmt.Println("Hello, World!")}
package main;
import "fmt";
func main() { fmt.Println("Hello, World!");}
package main;
import "fmt";
func main() { fmt.Println("Hello, World!");}
package main;
import "fmt";
func main() { fmt.Println("Hello, World!");}
f()
func factorial(n int) (int) { if (n < 2) { return 1 } return n * factorial(n -‐ 1)}
func factorial(n int) (int) { if (n < 2) { return 1 } return n * factorial(n -‐ 1)}
func factorial(n int) (int) { if (n < 2) { return 1 } return n * factorial(n -‐ 1)}
func factorial(n int) (int) { if (n < 2) { return 1 } return n * factorial(n -‐ 1)}
Go
int factorial(n int) { if (n < 2) { return 1 } return n * factorial(n -‐ 1)}
C++
:=
:=Да-да, навеяно Паскалем
«Динамические типы»
bool
string
int int8 int16 int32 int64uint uint8 uint16 uint32 uint64 uintptr
float32 float64
complex64 complex128
func main() { for c := 0; c != 10; c++ { fmt.Printf( "%d! = %d\n", c, factorial(c))
}}
var x int
var x int = 10
x := 10
var x int = 10
x := 10
Одно и то же
defer
«Стек блоков END»
func d() { defer fmt.Println("Before 2") defer fmt.Println("Before 1") fmt.Printf("a\n") return}
func d() { defer fmt.Println("Before 2") defer fmt.Println("Before 1") fmt.Printf("a\n") return}
aBefore 1Before 2
range
each в перле
package main
func main() { var list = []string{"a", "b"}
for k, v := range list { println(k, v) }}
_
Это не $_
package main
func main() { var list = []string{"a", "b"}
for k, v := range list { println(k, v) }}
package main
func main() { var list = []string{"a", "b"}
for k, v := range list { println(v) }}
package main
func main() { var list = []string{"a", "b"}
for k, v := range list { println(v) }}
range.go:5: k declared and not used
package main
func main() { var list = []string{"a", "b"}
for _, v := range list { println(v) }}
Похоже на (undef, $v) = @list;
package main
func main() { var list = []string{"a", "b"}
for _, v := range list { println(v) }}
Struct literal
Интерфейсы
Нет классов
Нет наследования
Есть методы
type I interface { Get() int Set(int)}
func assign_and_print(x I, v int) { x.Set(v) fmt.Printf("%v\n", x.Get())}
func assign_and_print(x I, v int) { x.Set(v) fmt.Printf("%v\n", x.Get())}
type s struct { i int}
func (x *s) Get() int { return x.i}
func (x *s) Set(i int) { x.i = i}
func assign_and_print(x I, v int) { x.Set(v) fmt.Printf("%v\n", x.Get())}
func main() { var y s assign_and_print(&y, 42)}
Пример 1
Wiki
func main() { http.HandleFunc("/view/", viewHandler) http.HandleFunc("/edit/", editHandler) http.HandleFunc("/save/", saveHandler) http.ListenAndServe(":8080", nil)}
func main() { http.HandleFunc("/view/", viewHandler) http.HandleFunc("/edit/", editHandler) http.HandleFunc("/save/", saveHandler) http.ListenAndServe(":8080", nil)}
func viewHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.Path[lenPath:] p, err := loadPage(title) if err == nil { fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body) } else { http.Redirect(w, r, "/edit/" + title, http.StatusFound) return }}
func viewHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.Path[lenPath:] p, err := loadPage(title) if err == nil { fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body) } else { http.Redirect(w, r, "/edit/" + title, http.StatusFound) return }}
func loadPage(title string) (*Page, os.Error) { filename := title + ".txt" body, err := ioutil.ReadFile(filename) if err != nil { return nil, err } return &Page{Title: title, Body: body}, nil}
func loadPage(title string) (*Page, os.Error) { filename := title + ".txt" body, err := ioutil.ReadFile(filename) if err != nil { return nil, err } return &Page{Title: title, Body: body}, nil}
type Page struct { Title string Body []byte}
func main() { http.HandleFunc("/view/", viewHandler) http.HandleFunc("/edit/", editHandler) http.HandleFunc("/save/", saveHandler) http.ListenAndServe(":8080", nil)}
func editHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.Path[lenPath:] p, err := loadPage(title) if err != nil { p = &Page{Title: title} } fmt.Fprintf(w, "<h1>Editing %s</h1>" + "<form action=\"/save/%s\" method=\"POST\">" + "<textarea name=\"body\">%s</textarea><br />" + "<input type=\"submit\" value=\"Save\" />" + "</form>", p.Title, p.Title, p.Body)}
func main() { http.HandleFunc("/view/", viewHandler) http.HandleFunc("/edit/", editHandler) http.HandleFunc("/save/", saveHandler) http.ListenAndServe(":8080", nil)}
func saveHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.Path[lenPath:] body := r.FormValue("body") p := &Page{Title: title, Body: []byte(body)} p.save() http.Redirect(w, r, "/view/" + title, http.StatusFound)}
func saveHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.Path[lenPath:] body := r.FormValue("body") p := &Page{Title: title, Body: []byte(body)} p.save() http.Redirect(w, r, "/view/" + title, http.StatusFound)}
func (p *Page) save() os.Error { filename := p.Title + ".txt" return ioutil.WriteFile(filename, p.Body, 0600)}
func (p *Page) save() os.Error { filename := p.Title + ".txt" return ioutil.WriteFile(filename, p.Body, 0600)}
p.save()
— Параллельность— Обмен данными между потоками
Горутиныи
каналы
-‐>
<-‐
Пример 2
Sleep sort
#!/bin/bashfunction f() { sleep "$1" echo "$1"}while [ -‐n "$1" ]do f "$1" & shiftdonewait
func main() { values := []int{3, 1, ..., 10} get_value = make(chan int) for _, x := range values { go send_value(x) } for range values { fmt.Println(<-‐ get_value) }}
func main() { values := []int{3, 1, ..., 10} get_value = make(chan int) for _, x := range values { go send_value(x) } for range values { fmt.Println(<-‐ get_value) }}
func main() { values := []int{3, 1, ..., 10} get_value = make(chan int) for _, x := range values { go send_value(x) } for range values { fmt.Println(<-‐ get_value) }}
var get_value chan int
get_value = make(chan int)
var get_value chan int
get_value = make(chan int)
get_value <-‐ x Запись в канал
var get_value chan int
get_value = make(chan int)
get_value <-‐ x Запись в канал
y := <-‐ get_value Чтение из канала
go f(x, y, z)
func main() { values := []int{3, 1, ..., 10} get_value = make(chan int) for _, x := range values { go send_value(x) } for range values { fmt.Println(<-‐ get_value) }}
func main() { values := []int{3, 1, ..., 10} get_value = make(chan int) for _, x := range values { go send_value(x) } for range values { fmt.Println(<-‐ get_value) }}
func main() { values := []int{3, 1, ..., 10} get_value = make(chan int) for _, x := range values { go send_value(x) } for range values { fmt.Println(<-‐ get_value) }}
func send_value(x int) { time.Sleep(int64(x) * 1E8) get_value <-‐ x}
func send_value(x int) { time.Sleep(int64(x) * 1E8) get_value <-‐ x}
func send_value(x int) { time.Sleep(int64(x) * 1E8) get_value <-‐ x}
— Стандартные модули— «CPAN»
golang.org/pkgarchive/tararchive/zipbigbufiobytescmathcompress/*container/*crypto/*debugebnfencoding
execexp/regexflagfmtgo/*hash/*http/cgihttp/fcgiimage/*io/ioutillogmail
netos/*path/filepathrpcruntime/*smtpsorttesting/*timeunicodewebsocketxml
code.google.com/p/*
github.com/*
Андрей Шитов [email protected]
Все тесты к этой презентации:github.com/ash/go-tests