====== 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