Язык 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
$	
  godoc	
  -­‐http=:6060




Локальный golang.org
«   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.go        interface.go          q3.go
addr_in_noninit.go   interface_vars.go     q4-­‐2.go
array.go             iota.go               q4-­‐4.go
assign-­‐new.go      iota_print-­‐1.go     q4.go
blank.go             iota_print-­‐2.go     q6.go
channel.go           iota_print.go         q7.go
close_channel.go     len.go                q9.go
complex.go           map.go                random-­‐select.go
copy-­‐array.go      map_autovivif.go      range-­‐string.go
db.go                map_non_existent.go   range.go
defer-­‐func.go      mul_int64.go          receiver.go
defer.go             openfile.go           recover.go
dial.go              panic.go              reslice.go
echo.go              pointer.go            sort-­‐delay-­‐1.go
even-­‐use.go        pp.go                 sort-­‐delay.go
even.go              println.go            sort.go
factorial.go         q10.go                string_range.go
fmt.go               q11.go                struct.go
goroutine.go         q12.go                switch.go
import_.go           q12a.go               type-­‐struct.go
init.go              q2-­‐2.go             var.go
int_method.go        q2-­‐3.go             variadic.go
Hello, World!
package	
  main

import	
  "fmt"

func	
  main()	
  {
	
  	
  	
  fmt.Println("Hello,	
  World!")
}
Многабукаф?
Java

class	
  HelloWorld	
  {
	
  	
  	
  	
  static	
  public
	
  	
  	
  	
  void	
  main(String	
  args[])	
  {
	
  	
  	
  	
  	
  	
  	
  	
  System.out.println(
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "Hello,	
  World!"
	
  	
  	
  	
  	
  	
  	
  	
  );
	
  	
  	
  	
  }
}
C++

#include<iostream>

int	
  main()	
  {
	
  	
  	
  	
  std::cout	
  <<	
  "Hello,	
  World!n";
	
  	
  	
  	
  return	
  0;
}
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!");
}
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)
}
Go
func	
  factorial(n	
  int)	
  (int)	
  {
	
  	
  	
  	
  if	
  (n	
  <	
  2)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  return	
  1
	
  	
  	
  	
  }
	
  	
  	
  	
  
	
  	
  	
  	
  return	
  n	
  *	
  factorial(n	
  -­‐	
  1)
}
C++
int	
  factorial(n	
  int)	
  {
	
  	
  	
  	
  if	
  (n	
  <	
  2)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  return	
  1
	
  	
  	
  	
  }
	
  	
  	
  	
  
	
  	
  	
  	
  return	
  n	
  *	
  factorial(n	
  -­‐	
  1)
}
:=
:=
Да-да, навеяно Паскалем
«Динамические типы»
bool

string

int	
  	
  int8	
  	
  int16	
  	
  int32	
  	
  int64
uint	
  uint8	
  uint16	
  uint32	
  uint64	
  
uintptr

float32	
  float64

complex64	
  complex128
func	
  main()	
  {
	
  	
  	
  	
  for	
  c	
  :=	
  0;	
  c	
  !=	
  10;	
  c++	
  {
	
   	
  	
  	
  	
  	
  fmt.Printf(
    	
  	
  	
  	
  	
  	
  	
  	
  "%d!	
  =	
  %dn",
    	
  	
  	
  	
  	
  	
  	
  	
  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("an")
	
  	
  	
  	
  
	
  	
  	
  	
  return
}
func	
  d()	
  {
	
  	
  	
  	
  defer	
  fmt.Println("Before	
  2")
	
  	
  	
  	
  defer	
  fmt.Println("Before	
  1")
	
  	
  	
  	
  
	
  	
  	
  	
  fmt.Printf("an")
	
  	
  	
  	
  
	
  	
  	
  	
  return
}
                            a
                            Before	
  1
                            Before	
  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("%vn",	
  x.Get())
}
func	
  assign_and_print(x	
  I,	
  v	
  int)	
  {
	
  	
  	
  	
  x.Set(v)
	
  	
  	
  	
  fmt.Printf("%vn",	
  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("%vn",	
  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/bash
function	
  f()	
  {
	
  	
  	
  	
  sleep	
  "$1"
	
  	
  	
  	
  echo	
  "$1"
}
while	
  [	
  -­‐n	
  "$1"	
  ]
do
	
  	
  	
  	
  f	
  "$1"	
  &
	
  	
  	
  	
  shift
done
wait
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/pkg
archive/tar   exec        net
archive/zip   exp/regex   os/*
big           flag        path/filepath
bufio         fmt         rpc
bytes         go/*        runtime/*
cmath         hash/*      smtp
compress/*    http/cgi    sort
container/*   http/fcgi   testing/*
crypto/*      image/*     time
debug         io/ioutil   unicode
ebnf          log         websocket
encoding      mail        xml
code.google.com/p/*
   github.com/*
Все тесты к этой презентации:
  github.com/ash/go-tests




   Андрей Шитов andy@shitov.ru

Язык программирования Go для Perl-программистов

  • 1.
  • 2.
    — Зачем знатьпро Go? — Откуда про него узнать? — Зачем нужен Go?
  • 4.
  • 5.
  • 6.
  • 7.
  • 11.
  • 12.
    Дух перла (совсемнемного) душок :-)
  • 13.
  • 14.
    UTF-8 всегда и везде Даже в именах переменных
  • 15.
    UTF-8 всегда и везде Даже в именах переменных Perl 6!
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
    « The Go programming language is an open source project to make programmers more productive.»
  • 24.
    « Perl is a general-purpose programming language originally developed for text manipulation »
  • 25.
    « Go is expressive, concise, clean, and efficient. »
  • 26.
    « The language is intended to be practical <. . .> rather than beautiful »
  • 27.
  • 28.
  • 29.
  • 30.
  • 32.
  • 33.
    Ни на чтоне похожие интерфейсы
  • 34.
    Нет ООП инаследования
  • 35.
    В начале 2012 обещают GO 1.0
  • 36.
  • 37.
    Не все старыепрограммы работают в новых релизах Go
  • 38.
    Не все старыепрограммы работают в новых релизах Go Perl 6!
  • 39.
  • 40.
  • 41.
    01-­‐hello.go interface.go q3.go addr_in_noninit.go interface_vars.go q4-­‐2.go array.go iota.go q4-­‐4.go assign-­‐new.go iota_print-­‐1.go q4.go blank.go iota_print-­‐2.go q6.go channel.go iota_print.go q7.go close_channel.go len.go q9.go complex.go map.go random-­‐select.go copy-­‐array.go map_autovivif.go range-­‐string.go db.go map_non_existent.go range.go defer-­‐func.go mul_int64.go receiver.go defer.go openfile.go recover.go dial.go panic.go reslice.go echo.go pointer.go sort-­‐delay-­‐1.go even-­‐use.go pp.go sort-­‐delay.go even.go println.go sort.go factorial.go q10.go string_range.go fmt.go q11.go struct.go goroutine.go q12.go switch.go import_.go q12a.go type-­‐struct.go init.go q2-­‐2.go var.go int_method.go q2-­‐3.go variadic.go
  • 42.
  • 43.
    package  main import  "fmt" func  main()  {      fmt.Println("Hello,  World!") }
  • 44.
  • 45.
    Java class  HelloWorld  {        static  public        void  main(String  args[])  {                System.out.println(                      "Hello,  World!"                );        } }
  • 46.
    C++ #include<iostream> int  main()  {        std::cout  <<  "Hello,  World!n";        return  0; }
  • 47.
    Go package  main import  "fmt" func  main()  {      fmt.Println("Hello,  World!") }
  • 48.
    package  main import  "fmt" func  main()  {      fmt.Println("Hello,  World!") }
  • 49.
  • 50.
    package  main import  "fmt" func  main()  {      fmt.Println("Hello,  World!") }
  • 51.
    package  main; import  "fmt"; func  main()  {      fmt.Println("Hello,  World!"); }
  • 52.
    package  main; import  "fmt"; func  main()  {      fmt.Println("Hello,  World!"); }
  • 53.
    package  main; import  "fmt"; func  main()  {      fmt.Println("Hello,  World!"); }
  • 54.
  • 55.
    func  factorial(n  int)  (int)  {        if  (n  <  2)  {                return  1        }                return  n  *  factorial(n  -­‐  1) }
  • 56.
    func  factorial(n  int)  (int)  {        if  (n  <  2)  {                return  1        }                return  n  *  factorial(n  -­‐  1) }
  • 57.
    func  factorial(n  int)  (int)  {        if  (n  <  2)  {                return  1        }                return  n  *  factorial(n  -­‐  1) }
  • 58.
    Go func  factorial(n  int)  (int)  {        if  (n  <  2)  {                return  1        }                return  n  *  factorial(n  -­‐  1) }
  • 59.
    C++ int  factorial(n  int)  {        if  (n  <  2)  {                return  1        }                return  n  *  factorial(n  -­‐  1) }
  • 60.
  • 61.
  • 62.
  • 63.
    bool string int    int8    int16    int32    int64 uint  uint8  uint16  uint32  uint64   uintptr float32  float64 complex64  complex128
  • 64.
    func  main()  {        for  c  :=  0;  c  !=  10;  c++  {            fmt.Printf(                "%d!  =  %dn",                c,  factorial(c))        } }
  • 65.
  • 66.
  • 67.
           x  :=  10
  • 68.
    var  x  int  =  10        x  :=  10 Одно и то же
  • 69.
  • 70.
  • 71.
    func  d()  {        defer  fmt.Println("Before  2")        defer  fmt.Println("Before  1")                fmt.Printf("an")                return }
  • 72.
    func  d()  {        defer  fmt.Println("Before  2")        defer  fmt.Println("Before  1")                fmt.Printf("an")                return } a Before  1 Before  2
  • 73.
  • 74.
  • 75.
    package  main func  main()  {        var  list  =  []string{"a",  "b"}        for  k,  v  :=  range  list  {                println(k,  v)        } }
  • 76.
  • 77.
  • 78.
    package  main func  main()  {        var  list  =  []string{"a",  "b"}        for  k,  v  :=  range  list  {                println(k,  v)        } }
  • 79.
    package  main func  main()  {        var  list  =  []string{"a",  "b"}        for  k,  v  :=  range  list  {                println(v)        } }
  • 80.
    package  main func  main()  {        var  list  =  []string{"a",  "b"}        for  k,  v  :=  range  list  {                println(v)        } } range.go:5:  k  declared  and  not  used
  • 81.
    package  main func  main()  {        var  list  =  []string{"a",  "b"}        for  _,  v  :=  range  list  {                println(v)        } }
  • 82.
  • 83.
    package  main func  main()  {        var  list  =  []string{"a",  "b"}        for  _,  v  :=  range  list  {                println(v)        } } Struct literal
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
    type  I  interface  {        Get()  int        Set(int) }
  • 89.
    func  assign_and_print(x  I,  v  int)  {        x.Set(v)        fmt.Printf("%vn",  x.Get()) }
  • 90.
    func  assign_and_print(x  I,  v  int)  {        x.Set(v)        fmt.Printf("%vn",  x.Get()) }
  • 91.
    type  s  struct  {        i  int }
  • 92.
    func  (x  *s)  Get()  int  {        return  x.i } func  (x  *s)  Set(i  int)  {        x.i  =  i }
  • 93.
    func  assign_and_print(x  I,  v  int)  {        x.Set(v)        fmt.Printf("%vn",  x.Get()) }
  • 94.
    func  main()  {        var  y  s        assign_and_print(&y,  42) }
  • 95.
  • 96.
    func  main()  {        http.HandleFunc("/view/",  viewHandler)        http.HandleFunc("/edit/",  editHandler)        http.HandleFunc("/save/",  saveHandler)                http.ListenAndServe(":8080",  nil) }
  • 97.
    func  main()  {        http.HandleFunc("/view/",  viewHandler)        http.HandleFunc("/edit/",  editHandler)        http.HandleFunc("/save/",  saveHandler)                http.ListenAndServe(":8080",  nil) }
  • 98.
    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        } }
  • 99.
    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        } }
  • 100.
    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 }
  • 101.
    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 }
  • 102.
    type  Page  struct  {        Title  string        Body  []byte }
  • 103.
    func  main()  {        http.HandleFunc("/view/",  viewHandler)        http.HandleFunc("/edit/",  editHandler)        http.HandleFunc("/save/",  saveHandler)                http.ListenAndServe(":8080",  nil) }
  • 104.
    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) }
  • 105.
    func  main()  {        http.HandleFunc("/view/",  viewHandler)        http.HandleFunc("/edit/",  editHandler)        http.HandleFunc("/save/",  saveHandler)                http.ListenAndServe(":8080",  nil) }
  • 106.
    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) }
  • 107.
    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) }
  • 108.
    func  (p  *Page)  save()  os.Error  {        filename  :=  p.Title  +  ".txt"        return  ioutil.WriteFile(filename,                                                          p.Body,  0600) }
  • 109.
    func  (p  *Page)  save()  os.Error  {        filename  :=  p.Title  +  ".txt"        return  ioutil.WriteFile(filename,                                                          p.Body,  0600) } p.save()
  • 110.
    — Параллельность — Обменданными между потоками
  • 111.
    Горутины и каналы
  • 112.
  • 113.
  • 114.
  • 115.
    #!/bin/bash function  f()  {        sleep  "$1"        echo  "$1" } while  [  -­‐n  "$1"  ] do        f  "$1"  &        shift done wait
  • 116.
    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)          } }
  • 117.
    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)          } }
  • 118.
    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)          } }
  • 119.
    var  get_value  chan  int        get_value  =  make(chan  int)
  • 120.
    var  get_value  chan  int        get_value  =  make(chan  int) get_value  <-­‐  x Запись в канал
  • 121.
    var  get_value  chan  int        get_value  =  make(chan  int) get_value  <-­‐  x Запись в канал y  :=  <-­‐  get_value Чтение из канала
  • 122.
  • 123.
    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)          } }
  • 124.
    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)          } }
  • 125.
    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)          } }
  • 126.
    func  send_value(x  int)  {          time.Sleep(int64(x)  *  1E8)          get_value  <-­‐  x }
  • 127.
    func  send_value(x  int)  {          time.Sleep(int64(x)  *  1E8)          get_value  <-­‐  x }
  • 128.
    func  send_value(x  int)  {          time.Sleep(int64(x)  *  1E8)          get_value  <-­‐  x }
  • 129.
  • 130.
    golang.org/pkg archive/tar exec net archive/zip exp/regex os/* big flag path/filepath bufio fmt rpc bytes go/* runtime/* cmath hash/* smtp compress/* http/cgi sort container/* http/fcgi testing/* crypto/* image/* time debug io/ioutil unicode ebnf log websocket encoding mail xml
  • 131.
  • 132.
    Все тесты кэтой презентации: github.com/ash/go-tests Андрей Шитов andy@shitov.ru