Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Другие языки > Введение в google Go


Автор: GrayCardinal 6.1.2010, 16:21
               Язык google "Go"
Go - новый мощнейший, экспериментальный, низкоуровневый язык программирования от Google. 
Адрес проекта:
http://golang.org

Мои простые примеры, которые демонстрируют основные возможности языка.
http://op.oaoontk.ru/GO/samples.tar.gz


            Установка.
Настройка среды. Рекомендую такие значения:
Код


export GOROOT=/usr/src/golang
export GOARCH=386
export GOOS=linux
export GOBIN=/usr/src/gobin
export PATH=$PATH:/usr/src/gobin


Сохраните эти переменные в файл и подгружайте с помощью "source" или "."
$ source /usr/src/golang/env.sh

Здесь GOROOT - каталог с сырцами (см ниже). GOBIN - каталог для исполняемых файлов Go. 
Изначально вы должны создать пустой каталог (RW) под испоняемые файлы. После сборки
из сырцов там будут лежать все необходимые программы (в том числе компилер 8g и линкер 8l)

Получить сырцы Go можно либо с помощью mercurial

Код

$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT

либо скачав последний снапшот с моего сайта:
http://op.oaoontk.ru/golang.tar.gz
В моем архиве уже есть ./env.sh. 
Сырцы распаковываем (если из архива) и пихаем в $GOROOT (/usr/src/golang)

Далее - сборка. 
ПРИМЕЧАНИЕ: перед сборкой все вышеописанные переменные должны быть установлены.
Заходим в $GOROOT/src и выполняем 
Код

$ make all

            Введение.
Почему Go ? Хочу отметить некоторые моменты, которые меня прельстили в этом языке (по сравнению с Си)
1. Нет хидеров. Вообще.
2. Быстрая компиляция. Это не шутка. Компиляция просто РЕАКТИВНАЯ.
3. Функции могут возвращать несколько значений.
4. Автоматическая сборка мусора.
5. Интерфейсы.
6. defer'ы
...

Вообще, по моему скромному мнению язык стоит изучить хотя бы для того, чтобы иметь представление 
об этом перспективном языке... Если после этого захотите вернуться к Си, никто Вам мешать не будет.

            
            Первая программа.
Хело ворлд, конечно... 

Код

package main

import fmt "fmt" // Package implementing formatted I/O.

func main() { 
    fmt.Println("Hello, world !") 


(обратите внимание на отсутствие точек с запятой)

Сохраним код в файл, допустим, 1.go Теперь его надо откомпилировать и слинковать.
Код

$ 8g 1.go
$ 8l 1.8
$ ./8.out
-> Hello world !


На моей паге аналогичная Си-программа компилировалась в 5 раз (!) дольше. К сожалению, на момент написания статьи,
нет возможности слинковать бинарник с шаровым go. Бинарник получается большой, но без всяких зависимостей. Т.е.
Код

$ ldd 8.out
->         statically linked

           
           Встроенные типы.
Я не буду перечислять все "простые" типы Go, просто посмотрите табличку вот здесь:
http://golang.org/doc/go_spec.html#Types
Массивы, слайсы,етк. разжую чуть позже...

            Переменные.
В Go все переменные строго типизированные. Переменные (в том числе массивы и слайсы) автоматически "обнуляются". 
Для определения переменной можно использовать два подхода. Первый - с помощью var:
Код

var varname Type

Второй - при помощи :=, к примеру так:
Код

varname := new(Type)

В Go есть указатели, однако отсутствует любая арифметика с ними. Еще одна особенность - нет "->". Точка используется
точно так же для указателей.

            Операторы.
Присутствуют if,for,switch. Из особенностей - отсутствие круглых скобок и автопреобразования в bool

Код

var i int
switch i { // OK
    case 0:
        fmt.Println("Ноль")
}

if i == 0 { // OK
}

if i {    // Error
}


отмечу, что отсутствует "while"

            Область видимости.
Для того, чтобы функция/тип/интерфейс был виден за пределами пакета, его имя должно начинаться с заглавной буквы.
Так же поля структуры, не с заглавной - будут недоступны "извне". А ля private.

            Типы.
Вы можете (и будете) определять типы. Вообще типы в Go имеют очень специфическое значение. Вот небольшой пример.
Код

package mailn

type MyType uint32     // Определить новый тип 

func main() {
    var p *MyType
    var i uint32
    p = new(MyType)
    i = *p // error
}


компиляция выдаст следующее:
Код

->./2.go:8: i declared and not used
->./2.go:10: cannot use *p (type MyType) as type uint32 in assignment

Первая ошибка - мы определили, но не использовали переменную. Да, это ошибка а не предупреждение как в Си.
Вторая строчка интересней. В ней говорится что _нельзя_ приравнивать MyType к uint32 ибо это _разные_ типы.
Так же при помощи type вы будете определять структуры и интерфейсы. Структура, она и в африке структура,
а интерфейсы рассмотрим чуть позже. Вот определение простого типа-структуры:
Код

type Mytype struct {
    a,b uint32
}        

 
                  Массивы.
Вот как определить массив:
Код

var varname [SIZE]type

- определить переменную-массив SIZE элементов типа type. В данном случае память выделится и "обнулится" автоматически.
Добавлю что SIZE не может быть переменной ! Если вы не знаете заранее размер массива, то вам нужны слайсы.
Если у вас указатель на массив, память можно выделить при помощи new (но не "make" !)
Код

buf *[100]int
buf = new([100]int)


        Слайсы.
По сути это тот же массив. Точнее ссылка на него. 
Определение слайса:
Код

var buf []type
buf = make([]type, SIZE)


(SIZE может быть как константой, так и переменной)
Т.е. вся разница в том, что размер не указывается, да память надо выделить вручную. Память для слайса выделяется при
помощи make (однако обнуляется так же автоматически).
Размер массива и слайса можно определить при помощи встроенной функции len.

        Хеш
Хеш, в данном контексте - привязка одного к другому. Все довольно просто.
Код

my_hash = make(map[string]string)
// my_hash - хеш.с привязкой строка-строка. Установить значение можно так:
my_hash["key"] = value
// Удалить ключ:
my_hash["key"] = 0, false


        range
Оператор "range" может быть использован совместно с массивами,слайсами,чанами (channels), хешами. Вроде ничего не забыл.
Использовать довольно просто:

Код

var buf [128]byte
for index,value := range buf {
    fmt.Printf ("%d %d\n", index, value)    
}    


        new или make ?
Для создания слайсов,хешей,чанов (channels) используется make. В остальных случаях - new.

        Функции.
В Go функции:
1. Имеют "привязку" к типу.
2. Могут возвращать несколько значений.

Рассмотрим на примере одной функции.
Код

    func (c *UDPConn) Read(b []byte) (n int, err os.Error)

c - привязка к типу. b - обязательный параметр (слайс) n - первое возвращаемое значение, err - второе. Чтобы использовать
данную функцию, нужна переменная типа *UDPConn. Её, к примеру, можно получить вызвав одну из соотв. функций пакета "net"
Условный пример 
Код

package main

import net "net"
 
func main() {
    var c *net.UDPConn
    var buf []byte
    buf = make([]byte,4096)
    c,_ = net.DialUDP(...)
    c.Read(buf)    
}


1 - Определяем новый пакет main. 
3 - Подгружаем модуль "net", который будет известен как net. Здесь стоит отметить, что никакие имена из модуля НЕ подгружаются.
Везде, где вы ссылаетесь на что-то из пакета, вы должны приписывать имя модуля. 
5 Точка входа любой Go-программы. Без аргументов. Если нужны аргументы - стоит копнуть модуль "flag". 
6 - определяем переменную-указатель на UDPConn, для дальнейшего использования. .
7-8 создаем буфер-слайс для последующего чтения. Обычный буфер, 4096 байт. 
9 Получаем инициализированную переменную типа *UDPConn. Однако функция net.DialUDP возвращает два значения, второе нам, положим, сейчас 
не нужно, заменяем ненужное символом подчеркивания. Если этого не сделать - получим ошибку при компиляции. 
10 Выполняем функцию Read типа UDPConn для переменной "c" c передачей одного значения. Почему без размера ? Размер массива/слайса всегда
можно узнать при помощи len, в данном случае - len(buf)
Всё это позволяет вам забыть слово "class", но не отказываться от ООП.

        Интерфейсы.
Интерфейсы - одна из вкусностей языка, которую нужно детальнейше изучить. Интерфейс - суть определение некоторых функций, которые может 
поддерживать некоторый тип. Чтобы тип отвечал интерфейсу, он должен реализовывать все функции этого интерфейса. Рассмотрим интерфейс io.Reader
Код

type Reader interface {
    Read(p []byte) (n int, err os.Error)
}

Описанная здесь функция Read реализована для многих типов. В том числе файлы и "bytes". Т.е. они поддерживают интерфейс io.Reader. Замечу,
что явно указывать какой интерфейс поддерживает данный тип вовсе необязательно. Просто реализуйте все функции интерфейса. Рассмотрим 
некоторые функции пакета bufio

Код

    func NewReader(rd io.Reader) *Reader

Функция требует один параметр - переменную для типа которой реализован интерфейс io.Reader. Это могут быть файлы, сокеты етк. Так же любой
 Ваш тип, для которого определена функция Read.

Код

    func NewWriter(wr io.Writer) *Writer

Аналогично, но для типа переменной wr должен быть реализован интерфейс io.Writer, т.е. функция Write.

Интерфейсы так же используются для переменных тип которых заранее неизвестен. Рассмотрим пакет list. Т.е. список. Вот демка использования
List. Использую List, ибо некоторые моменты его использования вовсе не очевидны, и не документированы.

Код

package main

import list "container/list"
import "fmt"
 
func main() {
   var m_list *list.List
   var str,str2 string;
   var m_element *list.Element

   m_list = list.New()
   str = "some text"
   m_list.PushBack (str)
   m_element = m_list.Front()
   str2 = m_element.Value.(string)
   fmt.Println(str2)
}

строки 1-6 думаю понятны.
7 - Объявляем указатель на объект List.
8 - нам нужны две строки
9 - и переменная типа *list.Element
11 - Создаем новый объект типа List.
12-13 - добавляем строку в конец списка.
рассмотрим более детально функцию PushBack

func (l *List) PushBack(value interface{}) *Element {
Функция для типа "указатель на List". Параметр value должен отвечать интерфейсу... пустом интерфейсу. Т.е. можете пихать переменные любого 
типа, без всякого преобразования.  Дальше интереснее. 
14 - берем первый элемент списка.
15. Извлекаем значение из элемента списка. Элемент имеет следующую структуру:
Код

type Element struct {
    Value interface{}
}

Как видно, значение имеет тип, поддерживающий пустой интерфейс. Любой тип. Однако здесь необходимо обратное преобразование. Для
такого преобразования просто добавляется .(нужный тип). В данном случае это .(string).
16. Вывод исходной строки.

        defer'ы
defer'ы, определяют функции, которые будут выполнены по завершению данной функции. Приведу простой пример, взятый из GoCourse
Код

func data(name string) string {
    f := os.Open(name, os.O_RDONLY, 0)
    defer f.close ()
    contents := io.ReadAll(f)
    return contents
}


        Goroutines
Если в Си эквиваленте - просто треды. Новый тред запускается при помощи оператора "go". Просто запустить "go" с одним параметром -
функцией. Она будет выполнятся в новом треде, вплоть до завершения. Как управлять goroutine'ами, пока не понятно. 
Код

func routine () {
}
...
go routine ()

Стоит отметить, что goroutine изначально имеет минимальный стек и сама расширяет его по мере необходимости.

        Channels (чаны).
Пусть будут чанами. Чаны - средство передачи данных между потоками (goroutines). Ежели по "Си" - просто труба. На самом деле 
чаны имеют гораздо большую функциональность. 
Код

var all chan int
var recv_only <-chan int
var send_only chan<- int
all = make(chan int, [size])
recv_only = make(<-chan int, [size])
send_only = make(chan<- int, [size])

1 - чан в обе стороны
2 - чан только для чтения
3 - чан только для записи

Автор: Фантом 6.1.2010, 16:37
Короче говоря, чуток видоизмененный Паскаль (в его современном виде) с наполовину C-подобным синтаксисом.  smile 

Автор: bilbobagginz 6.1.2010, 16:39
GrayCardinal, на хомяке проекта (кстати символ языка какой-то грызун... хомяк наверное)
есть упоминание о каких-то свойствах языка Go, делающим его удобным в параллельном программировании.
Можешь привести пример кода, который напр. распараллеливает что-то там... я не знаю ?

P.S.:
и еще выдели код под синтакс Java, по-моему прокатит, а команды и скрипты подкрась синтаксис по языку Perl.

Автор: GrayCardinal 6.1.2010, 17:30
bilbobagginz
С кодом проблемы... Вроде был какой-то недосервак... 
Я тут cp на Go перевел. Теперь работает в два раза дольше  smile 

Автор: Wisdom 6.1.2010, 17:53
Похоже, что в лаборатории безумного гения скрестили C с Паскалем, полученное "нечто" кастрировали в синтаксисе, добавили некоторых "неведомых примочек" и получили новый язык.. 
Цитата

Почему Go ? Хочу отметить некоторые моменты, которые меня прельстили в этом языке (по сравнению с Си)
1. Нет хидеров. Вообще.

Сомнительное преимущество. ВЧем же вас хэдэры не устраивают?
Цитата

Быстрая компиляция. Это не шутка. Компиляция просто РЕАКТИВНАЯ.

Хотелось бы узнать, за счет чего такая "реактивная" компиляция достигается?
Цитата

3. Функции могут возвращать несколько значений.

Ну, ребят.. круто конечно, но надо ли?  smile 
Цитата

4. Автоматическая сборка мусора.

 smile 
Цитата

5. Интерфейсы.

Эм..
**************************
1. Отсутствие круглых скобок в switch затрудняет чтение кода.
2. Пример с определением типов очень остроумен, конечно.. И ошибка в GO является, конечно же, несомненным преимуществом перед предупреждением в С :\
3. Пространство имен. Регистрозависимый функционал, это, конечно, круто.. опять же, зачем?
4. Объявление массивов без комментариев.
Ладно.. пожалуй не буду зудеть smile Описать язык в двух словах, конечно, трудно.
Возникло желание рассмотреть поближе, но по ссылке на адрес проекта нечаво нет оО

Автор: GrayCardinal 6.1.2010, 17:55
Wisdom
Прошу не пинать меня за язык, у меня только статья, не более smile

Автор: MAKCim 6.1.2010, 18:33
у меня make all вылетает с ошибкой
Код

bash /home/rei3er/install/go/golang/src/make.bash
bash: /home/rei3er/install/go/golang/src/make.bash: No such file or directory
make: *** [build] Error 127

никакого make.bash нет в $GOROOT/src

Автор: bilbobagginz 6.1.2010, 18:50
Цитата(Wisdom @  6.1.2010,  16:53 Найти цитируемый пост)
Возникло желание рассмотреть поближе, но по ссылке на адрес проекта нечаво нет оО

что значит нечаво нет?!?!
код, дока, хауту, книги... нечаво нет.
Цитата(Wisdom @  6.1.2010,  16:53 Найти цитируемый пост)
Хотелось бы узнать, за счет чего такая "реактивная" компиляция достигается?

на сайт, где ничего нет - марш smile

Автор: powerfox 6.1.2010, 20:40
Цитата(Wisdom @  6.1.2010,  18:53 Найти цитируемый пост)
Сомнительное преимущество. ВЧем же вас хэдэры не устраивают?

Это из области «почему заголовочные файлы не обеспечивают модульность».

Цитата(bilbobagginz @  6.1.2010,  17:39 Найти цитируемый пост)
есть упоминание о каких-то свойствах языка Go, делающим его удобным в параллельном программировании.

Судя по описанию, так это вообще основная фишка языка.
GrayCardinal, дуй дописывать примеры smile


Автор: kosmonaFFFt 6.1.2010, 22:15
Хм... ИМХО в параллельном программировании более удобен был бы erlang smile
Лично мне не нравится отсутствие скобок в if/switch и местами очень паскалеподобный синтаксис...
Да и с областью видимости, которая зависит от регистра первой буквы тоже не очень придумали...

З.Ы. Чуть не забыл - если язык завоюет какую-нибудь популярность, под него еще придется ждать приличную IDE...

Автор: GrayCardinal 7.1.2010, 11:33
powerfox
Не, сначала бобика доделаю  smile

Добавлено через 14 минут и 32 секунды
kosmonaFFFt
подсветка для Vim уже есть smile

Автор: GrayCardinal 7.1.2010, 18:32
Как юзать "основную фишку", разберусь, отпишусь чуть позже.

Автор: GrayCardinal 7.1.2010, 19:40
http://forum.vingrad.ru/forum/act-ST/f-69/t-286479/unread-1.html
Похоливаримс ?

Автор: MAKCim 8.1.2010, 12:32
не совсем понятно, как выделяется память в Go для объектов, к примеру такой код
Код

package main

import "fmt"

func main() {
    v1 := 1
    v2 := new(int)
    fmt.Printf("%p, %p\n", &v1, v2)
}

выдает
0x7EFF01CD1010, 0x7EFF01CD1018
что явно соответствует выделению памяти для v1 и v2 на стеке, хотя по идее new должен работать с brk/mmap хипом

Автор: GrayCardinal 13.1.2010, 14:02
Мдя. Похоже придется долго и упорно объяснять разработчикам что же они сделали  smile 

Автор: GrayCardinal 13.1.2010, 15:34
Добавил сэмплы на основные моменты языка... Может кому помогут...

Автор: powerfox 13.1.2010, 16:33
Цитата(GrayCardinal @  13.1.2010,  15:02 Найти цитируемый пост)
Мдя. Похоже придется долго и упорно объяснять разработчикам что же они сделали  smile 

Если ты посмотришь на имена разработчиков, то поймёшь, что это не те люди, которые не знают, что делают ;)

Автор: GrayCardinal 13.1.2010, 16:56
powerfox
Угу. Но что такое shutdown(2) пришлось разжевывать. Хотя, возможно, то был не разработчик :0

Автор: GrayCardinal 13.1.2010, 19:22
ЗЫ
А я их таки раскусил. Главная фишка - юзай интерфейс, остальное - не твое дело smile

Автор: GrayCardinal 13.1.2010, 20:15
МЛЯ. бродкаст для UDP... ЗАБЫЛИ

Добавлено через 3 минуты и 30 секунд
Ай ладно. shutdown дописал, можно и бродкаст дописать 

Автор: GrayCardinal 15.1.2010, 16:19
Вот тут кое-чего написал про Go
http://olegpuchinin.blogspot.com/

Автор: GrayCardinal 15.1.2010, 18:25
Хочу накатать вторую статью. Жду мнений по поводу что в ней лучше осветить ?

Автор: Void 15.1.2010, 21:16
Цитата(GrayCardinal @  15.1.2010,  20:25 Найти цитируемый пост)
Жду мнений по поводу что в ней лучше осветить ? 

Concurrency, каналы. На реальной небольшой задаче, где оно требуется.

Автор: GrayCardinal 15.1.2010, 23:35
Void
ОК

Автор: GrayCardinal 16.1.2010, 13:24
MAKCim

Цитата

выдает
0x7EFF01CD1010, 0x7EFF01CD1018
что явно соответствует выделению памяти для v1 и v2 на стеке, хотя по идее new должен работать с brk/mmap хипом 

Угу. Как я понял, память выделяется только из стека. И это гуд, ибо тред-сэйф smile

Автор: GrayCardinal 16.1.2010, 14:06
 smile  smile  smile  smile  smile  smile  smile 
 smile  smile  smile  smile 

Автор: kosmonaFFFt 17.1.2010, 13:06
GrayCardinal, подсветка для вима и IDE с автокомплитом, подсказаками по функциям и т. д. это две абсолютно разные вещи... smile

Автор: GrayCardinal 17.1.2010, 19:51
kosmonaFFFt
Ну, ежели охота ждать годик-другой приличную IDE, сиё есть Ваши проблемы. А мне и с Vim+Go+silentbob хорошо smile

Автор: Lazin 17.1.2010, 23:18
Цитата(Wisdom @  6.1.2010,  17:53 Найти цитируемый пост)
1. Отсутствие круглых скобок в switch затрудняет чтение кода.
2. Пример с определением типов очень остроумен, конечно.. И ошибка в GO является, конечно же, несомненным преимуществом перед предупреждением в С :\
3. Пространство имен. Регистрозависимый функционал, это, конечно, круто.. опять же, зачем?
4. Объявление массивов без комментариев.

в языке очень остроумно реализованы интерфейсы, а так-же поддерживаются coroutines(aka goroutines) и каналы с мэйлбоксами (aka channels), а им круглые скобочки в switch подавай smile 

Автор: GrayCardinal 18.1.2010, 11:29
Кстати, скобки можно ставить. Правда не нужно smile
 

Автор: kosmonaFFFt 18.1.2010, 17:30
Цитата(GrayCardinal @  18.1.2010,  11:29 Найти цитируемый пост)
Кстати, скобки можно ставить. Правда не нужно 


Ну это кому как... smile Но то что можно - это хорошо... )

Автор: suffrage 16.6.2010, 16:50
Теперь у нас появился свой http://golanguage.ru

Милости просим

Автор: GrayCardinal 16.6.2010, 16:53
suffrage
Рад что ты занялся рекламой smile

Автор: Masha7 19.7.2011, 13:15
Все это только мне напоминает Паскаль?smile










_______________________________________________________________________________


http://www.koptilni.com/http://www.kombains.com/http://www.turizm-for-you.ru/http://www.web-gangsters.ru/http://www.samurai-web.ru/http://www.web2-technology.ru/http://www.udovolstvie-rus.ru/http://lipstroi.ru/http://www.almawarid.net/http://www.anti-facebook.com/http://www.social-club.net/http://www.pro-odnoklassnikov.com/http://www.receptygoda.ru/http://www.avtomobils-news.ru/http://www.santehnika-russia.ru/http://www.vibropress-russia.com/http://www.webstalkers.ru/http://www.good-remonts.ru/http://www.yspeshno.ru/

Автор: k0rvin 20.7.2011, 19:33
Цитата(Masha7 @ 19.7.2011,  13:15)
Все это только мне напоминает Паскаль?smile

только тебе

Автор: bsa 12.8.2016, 14:58
Смотрю, тема заглохла. Видать те, кто изучил Go вопросов не имеют, а те кто не изучал - и подавно. smile

Автор: Olej 22.12.2016, 00:39
Цитата(bsa @ 12.8.2016,  14:58)
Смотрю, тема заглохла. Видать те, кто изучил Go вопросов не имеют, а те кто не изучал - и подавно. smile

http://mylinuxprog.blogspot.com/2014/08/go.html

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)