Примеры кода Go

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Примеры кода Go

Непрочитанное сообщение Olej » 02 июн 2016, 14:24

Эта тема переползла сюда из Инструменты Go:
В книге много интересных и полезных примеров кода (в отличие от обычных для большинства книг примеров бла-бла-бла, высосанных из пальца).
Я буду здесь отмечать (себе на памятку) только те немногие, которые особо полезны на практике.
Таким безусловно является обработка опций командной строки запуска программы, на манер того, что делает POSIX getopt().
Но там уже слишком много набралось по инструментарию Go (компиляция, редактирование и форматирование кода, тестирование, онлайн компиляторы и др.), тема сильно перегружена, поэтому всё, что касается именно примеров кода Go - выносим сюда.

Помещать сюда я буду только те примеры кода, которые мне покажутся красивыми. Это означает что:
- это не обучение программированию, или даже языку Go - считаем, что читатель знает достаточно обстоятельно C или C++ или Python (а ещё лучше "и" ;-) )
- обсуждаем конструкции, которые моделируют некоторые аналогии известным элементам C, C++, Python или других языков - как это будет выглядеть в Go (или, наоборот, как это будет противопоставлено в Go)

Т.е. я накапливаю здесь для себя справочник нетривиальных конструкций Go ... но если кого заинтересует что-то другое, то мы и это рассмотрим здесь.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Примеры кода Go

Непрочитанное сообщение Olej » 02 июн 2016, 19:55

Код: Выделить всё

[olej@dell vector]$ gofmt --help
usage: gofmt [flags] [path ...]
  -cpuprofile string
        write cpu profile to this file
  -d    display diffs instead of rewriting files
  -e    report all errors (not just the first 10 on different lines)
  -l    list files whose formatting differs from gofmt's
  -r string
        rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')
  -s    simplify code
  -w    write result to (source) file instead of stdout

[olej@dell vector]$ gofmt -w -e vector.go

Код: Выделить всё

// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
package main

import "fmt"

func appendInt(x []int, y int) []int {
	var z []int
	zlen := len(x) + 1
	if zlen <= cap(x) { // Имеется место для роста. Расширяем срез.
		z = x[:zlen]
	} else {
		// Места для роста нет. Выделяем новый массив. Увеличиваем
		// в два раза для линейной амортизированнной слохности.
		zcap := zlen
		if zcap < 2*len(x) {
			zcap = 2 * len(x)
		}
		z = make([]int, zlen, zcap)
		copy(z, x) // Встроенная функция; см. текст раздела
	}
	z[len(x)] = y
	return z
}

func main() {
	var x, y []int
	for i := 0; i < 10; i++ {
		y = appendInt(x, i)
		fmt.Printf("%d  cap=%d\t%v\n", i, cap(y), y)
		x = y
	}
}

Код: Выделить всё

[olej@dell vector]$ ./vector 
0  cap=1	[0]
1  cap=2	[0 1]
2  cap=4	[0 1 2]
3  cap=4	[0 1 2 3]
4  cap=8	[0 1 2 3 4]
5  cap=8	[0 1 2 3 4 5]
6  cap=8	[0 1 2 3 4 5 6]
7  cap=8	[0 1 2 3 4 5 6 7]
8  cap=16	[0 1 2 3 4 5 6 7 8]
9  cap=16	[0 1 2 3 4 5 6 7 8 9]
Этот пример прост (до примитивного).
Но он показывает как срезы Go используются в том качестве, как vector<> из C++ STL, причём показывает как это делается, скрывая под реализацией базовый массив, над которым надстроен срез (и массива здесь, собственно, не видно).
И делается расширение в точности так же, как это реализовано в большинстве реализаций STL.
Вложения
vector.png

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Примеры кода Go

Непрочитанное сообщение Olej » 02 июн 2016, 20:34

Olej писал(а): Этот пример прост (до примитивного).
Мы ранее установили golang-shared.

Код: Выделить всё

[olej@dell tasks]$ dnf list installed golang*
Последняя проверка окончания срока действия метаданных: 3:38:05 назад, Thu Jun  2 16:43:33 2016.
Установленные пакеты
golang.x86_64                                                   1.5.4-1.fc23                                                            @System 
golang-bin.x86_64                                               1.5.4-1.fc23                                                            @updates
golang-docs.noarch                                              1.5.4-1.fc23                                                            @updates
golang-godoc.x86_64                                             1:0-3.0.hga7e14835e46b.fc23                                             @fedora 
golang-shared.x86_64                                            1.5.4-1.fc23                                                            @updates
golang-src.noarch                                               1.5.4-1.fc23                                                            @updates
Это типовая статическая сборка GoLang :

Код: Выделить всё

[olej@dell vector]$ go build -compiler gc -o vectors vector.go 
[olej@dell vector]$ ls -l vectors
-rwxr-xr-x. 1 olej olej 2367640 июн  2 20:26 vectors
[olej@dell vector]$ ldd vectors
	не является динамическим исполняемым файлом
[olej@dell vector]$ ./vectors
0  cap=1	[0]
1  cap=2	[0 1]
2  cap=4	[0 1 2]
3  cap=4	[0 1 2 3]
4  cap=8	[0 1 2 3 4]
5  cap=8	[0 1 2 3 4 5]
6  cap=8	[0 1 2 3 4 5 6]
7  cap=8	[0 1 2 3 4 5 6 7]
8  cap=16	[0 1 2 3 4 5 6 7 8]
9  cap=16	[0 1 2 3 4 5 6 7 8 9]
А это динамическая сборка с разделяемыми библиотеками Linux (которая, похоже, появилась только с версии 1.5 GoLang) :

Код: Выделить всё

[olej@dell vector]$ go build -compiler gc -linkshared -o vectord vector.go 
[olej@dell vector]$ ls -l vectord
-rwxr-xr-x. 1 olej olej 16056 июн  2 20:29 vectord
[olej@dell vector]$ ldd vectord
	linux-vdso.so.1 (0x00007ffe1cafb000)
	libstd.so => /usr/lib/golang/pkg/linux_amd64_dynlink/libstd.so (0x00007fa3a6682000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fa3a62a3000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fa3a6086000)
	/lib64/ld-linux-x86-64.so.2 (0x00005579aafbc000)
[olej@dell vector]$ ./vectord
0  cap=1	[0]
1  cap=2	[0 1]
2  cap=4	[0 1 2]
3  cap=4	[0 1 2 3]
4  cap=8	[0 1 2 3 4]
5  cap=8	[0 1 2 3 4 5]
6  cap=8	[0 1 2 3 4 5 6]
7  cap=8	[0 1 2 3 4 5 6 7]
8  cap=16	[0 1 2 3 4 5 6 7 8]
9  cap=16	[0 1 2 3 4 5 6 7 8 9]

Сравните размеры исполнимых ELF-файлов:

Код: Выделить всё

[olej@dell vector]$ ls -l vector* | grep x
-rwxr-xr-x. 1 olej olej   16056 июн  2 20:29 vectord
-rwxr-xr-x. 1 olej olej 2367640 июн  2 20:26 vectors

Код: Выделить всё

[olej@dell vector]$ file vector*
vector0.go:  C source, UTF-8 Unicode text
vectord:     ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=11bdf4043de1f94ab1a69ea77474c3fb76cefbbe, not stripped
vector.go:   C source, UTF-8 Unicode text
vector.hist: C source, UTF-8 Unicode text
vectors:     ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Примеры кода Go

Непрочитанное сообщение Olej » 07 окт 2016, 21:23

Пример - проще не бывает! :lol:

Код: Выделить всё

package main
import "fmt"

func main() {
        fmt.Println("Hello, 世界")
}
(взято из книги: Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.)
Что это означает: 世界 - я представления не имею.
Но отлично иллюстрирует, как Go использует UNICODE.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Примеры кода Go

Непрочитанное сообщение Olej » 08 окт 2016, 20:28

Olej писал(а): Что это означает: 世界 - я представления не имею.
Вообще то, мне всегда было непонятно:
- если Unicode-стандарт предусматривает 32-бит кодирование для любых символов любых языков (и там найдётся место для племени мумбу-юмбу)...
- ну а UTF-8 - один из (лучших!) способов кодирования, представления кодов Unicode...
- то почему в программах на языках C и C++ нужно обязательно переустанавливать локаль ... что-то типа:

Код: Выделить всё

setlocale( LC_CTYPE, "ru_RU.utf8" );
- или на C++:

Код: Выделить всё

locale::global( locale( "" ) );
- зачем?
- даже если по стандарту старых языков C и C++ локаль по умолчанию и устанавливается в "C" или "POSIX"...

Когда Go так замечательно работает (без всяких телодвижений!) хоть с китайским языком, хоть с русским...

Аватара пользователя
perseus
Писатель
Сообщения: 99
Зарегистрирован: 11 май 2017, 18:01
Откуда: Щёлково, Московская обл.
Контактная информация:

Re: Примеры кода Go

Непрочитанное сообщение perseus » 13 май 2017, 20:33

Olej писал(а):
Olej писал(а): Что это означает: 世界 - я представления не имею.
на китайском языке это означает "мир"
"hello 世界" == "hello world"

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Примеры кода Go

Непрочитанное сообщение Olej » 13 май 2017, 21:15

perseus писал(а): на китайском языке это означает "мир"
"hello 世界" == "hello world"
Мне это, вообще-то говоря, всё равно ... даже если бы это был китайский мат :lol:
Меня именно такой литерал заинтересовал (я его списал :lol: ) в текстах Кернигана, одного из идеологов и авторов Go ... а до этого автора UTF-8 кодировки для OS Plan 9.
Конечно, Кернигана не мог удержаться от демонстрации многоязыковой прозрачности языка Go, полностью построенного на UTF-8 ... даже не взирая на то, что, например, в Windows UTF-8 совершенно противоестественная кодировка, и для представления UNICODE они используют UTF-16.
А в Go так и декларируется: Go везде использует UTF-8.

Уже после такого примера с китайскими литералами, я стал экспериментировать с мультиязычными именами переменных (и всех других объектов). Там во многих примерах у меня переменные, если вы обратили внимание, именованные на русском языке ... и на греческом - общепринятые обозначения...

... вот в этом месте я хотел зацитировать такие символы-переменные, но только редактор этого форума от этого впадает в ступор :-o :-(

А вот Go может - попробуйте в своём коде ... как может и OpenOffice, в котором я вам и зацитирую... :lol:
Вложения
s1.png

Аватара пользователя
perseus
Писатель
Сообщения: 99
Зарегистрирован: 11 май 2017, 18:01
Откуда: Щёлково, Московская обл.
Контактная информация:

Re: Примеры кода Go

Непрочитанное сообщение perseus » 09 июн 2017, 21:12

А вот Go может - попробуйте в своём коде ... как может и OpenOffice, в котором я вам и зацитирую... :lol:
Да, я видел это в вашем конспекте посвящённом языку Go, и в своих программах пробовал. Это действительно способствует для написания интернациональных программ на go или наоборот сугубо национальных. Выбор символов огромный. ;-)
В go есть даже такой тип как rune который представляет символы unicod и кучу методов к этому типу для работы с ним

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 7 гостей