====== Go (Golang): язык программирования общего назначения ===== Язык с "упором" на простоту синтаксиса, быструю компиляцию, многопоточность и хорошее сетевые возможности. На синтаксис языка повлияли Си, Pascal, Python, заметно влияние Java, Haskell(?). Основы языка быстро учатся, программки легко пишутся, легко компилируются и кросс-компилируются для большого множества архитектур и платформ. ===== Ссылки на важные ресурсы по Go ===== Хотя язык быстро развивается и сообщество программистов, использующих Go, стремительно растет, ресурсов для обучения на русском языке в сети не слишком много. - Статья о Go в Wikipedia [[https://ru.wikipedia.org/wiki/Go|Go на Wikipedia]] - Перевод книги Калеба Докси [[http://golang-book.ru/|Введение в программирование на Go]] - Русский блог о Go (новости, статьи, ссылки, "тулзовины") [[http://4gophers.ru/|Язык программирования Go]] - Основной сайт поддержки и документации (docs, specs, packs, blog) [[https://golang.org/|The Go Programming Language ]] - Сайты с коллекциями примеров: [[https://gobyexample.com/|Go by Example]], [[http://golang-examples.tumblr.com/|Golang Examples]] и сайт примеров на разных языках, включая Go [[http://rosettacode.org/wiki/Category:Programming_Tasks|Rosetta Code]], и о работе с сетью [[https://jan.newmarch.name/go/|Network programming with Go by Jan Newmarch]] - Хаб языка Go на портале [[http://habrahabr.ru/hub/go/|Хабрахабр]] - Песочница для работы с простыми программами на Go в режиме online [[https://play.golang.org/|The Go Playground]] ===== Немного истории ===== ===== Установка бинарного дистрибутива ===== - скачиваем по ссылке [[https://storage.googleapis.com/golang/go1.4.3.linux-386.tar.gz|бинарник версии 1.4.3]]; - распаковываем в домашней директории под именем $HOME/go; - устанавливаем системные переменные и изменения в переменной $PATH путем редактирования файла .profile export GOROOT="$HOME/go" export GOPATH="$HOME/mygoprojects" export GOBIN="$HOME/mygoprojects/bin"и в переменной $PATH:PATH=$HOME/go/bin:$PATH" ===== Основные возможности ===== ===== Структура программы ===== ==== Минимальный набор элементов ==== package main import "fmt" func main() { fmt.Println("Hello, world!") } ===== Особенности синтаксиса (и семантики) ===== ==== Комментарии ==== Go использует оба типа комментариев в стиле Си: строчные (начинающиеся с // …) и блочные (/**/). Строчный комментарий рассматривается компилятором как перевод строки. Блочный, располагающийся на одной строке — как пробел, на нескольких строках — как перевод строки. ==== Базовые примитивные типы данных ==== === Булев тип === bool --- тип логических значений (''true'' и ''false''), поддерживаются логические операции ''!'', ''&&'', ''||''. === Тип целых со знаком === int, int8, int16, int32, int64 -- число указывает сколько бит используется для представления типа. Тип int является машинно-зависимым, его размер зависит от архитектуры используемого компьютера. === Тип целых без знака === uint, uint8, uint16, uint32, uint64 -- число указывает сколько бит используется для представления типа. Тип uint является машинно-зависимым, его размер зависит от архитектуры используемого компьютера. === Тип чисел с плавающей точкой === float32, float64 -- число указывает сколько бит используется для представления типа. === Синонимы === byte, rune ==== Определение переменных и констант ==== === Константы === === Переменные === Полная форма задания переменных выглядит примерно так: var x float64 = 1.234 Значения можно присвоить и позже, более того, при определении переменной будет проведена инициализация в нулевое (для данного типа данных) значение var x float64 print (x) +0.000000e+000 Но так как поддерживается динамическая типизация, то можно, наоборот, присвоить значение и тип будет выведен: var x = 1.234 print (x) +1.234000e+000 или даже проще (как присваивание в Pascal'е): x := 1.234 print (x) +1.234000e+000 ==== Базовые сложные типы данных ==== === Строки === === Массивы === === Срезы === === Отображения (ассоциативные массивы) === === Структуры === Структуры --- с одной стороны напоминают таковые в Си, с другой, вместе с методами, --- это возможность некоторой разновидности (или подобия ООП) в языке Go. Рассмотрим на примере. Создадим простейшую структуру, описывающую ученика ФМШ: type pupil struct { name string lastname string age int32 height float32 weight float32 group int32 } Определить новую переменную данного типа можно и объявлением: var dima pupil (поля будут инициализированы нулями и пустыми строками), можно сделать более java-образно, с созданием указателя: var dima = new(pupil) (об указателях, в другой раз). Но можно сделать инициализацию в стиле Go: dima := pupil{name: "Dima", group: 412} (пропущенные поля вновь будут инициализированы нулями) Теперь к свойствам можно обращаться в ООП-стиле: fmt.Println(dima.name, dima.group) === Методы === Методы, если мы хотим их использовать как в ООП, задаются немного хитрее, нежели свойства-поля. Вот, попробуем вычислить "гармоническое телосложение" по формуле Брока func (p pupil) habitus() float32 { return ((p.height - 110) - p.weight) } После ключевого слова 'func' мы видим "получателя", т.е. задаем тип, с которым будем работать наш метод. Тогда для школьника dima мы можем сделать проверку телосложения: dima := pupil{name: "Dima", group: 412, heigh: 170, weight: 68} fmt.Println(dima.name, dima.habitus()) === Интерфейсы === ==== Типы данных, определяемые пользователем ==== ==== Вывод и ввод (простой вариант) ==== === Вывод === package main func main() { print("Hello", " world!"); } Тем не менее, стандартным способом вывода считается такая конструкция: package main import "fmt" func main() { x := 3.1415 fmt.Println("pi=", x) } === Ввод === == Попроще == package main import "fmt" func main() { var s string var i int if _, err := fmt.Scan(&s, &i); err == nil && i == 75000 { fmt.Println("good") } else { fmt.Println("wrong") } } для чтения строки можно использовать fmt.Scanln == Продвинутее == Используется буфер! package main import ( "bufio" "fmt" "os" "strconv" "strings" ) func main() { in := bufio.NewReader(os.Stdin) fmt.Print("Enter string: ") s, err := in.ReadString('\n') if err != nil { fmt.Println(err) return } s = strings.TrimSpace(s) fmt.Print("Enter 75000: ") s, err = in.ReadString('\n') if err != nil { fmt.Println(err) return } n, err := strconv.Atoi(strings.TrimSpace(s)) if err != nil { fmt.Println(err) return } if n != 75000 { fmt.Println("fail: not 75000") return } fmt.Println("Good") } Примеры взяты тут: [[http://rosettacode.org/wiki/User_input/Text#Go|Rosetta Code]] Скрытый раздел ===== Создание собственного web-сервера ===== На основе статей [[https://golang.org/doc/articles/wiki/|Writing Web Applications]] и частично [[https://astaxie.gitbooks.io/build-web-application-with-golang/content/en//|Build Web Application with Golang]], [[https://jan.newmarch.name/go/|Network programming with Go]]. Замечательная книга товарища astaxie в настоящий момент переводится на русский язык, и нужные нам главы уже доступны на русском: [[https://github.com/astaxie/build-web-application-with-golang/blob/master/ru/04.1.md|4.1 Работа с формами]] Пока, вот минимальный код: package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:]) } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) } просто сохраняем (напр., servak.go) запускаем ''go run servak.go'' и в браузере пробуем увидеть ответ по адресу http://127.0.0.1:8080/anything