Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 Languages
 С
 GNU С Library 
 Qt 
 STL 
 Threads 
 C++ 
 Samples 
 stanford.edu 
 ANSI C
 Libs
 LD
 Socket
 Pusher
 Pipes
 Encryption
 Plugin
 Inter-Process
 Errors
 Deep C Secrets
 C + UNIX
 Linked Lists / Trees
 Asm
 Perl
 Python
 Shell
 Erlang
 Go
 Rust
 Алгоритмы
NEWS
Последние статьи :
  Тренажёр 16.01   
  Эльбрус 05.12   
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
 
TOP 20
 Secure Programming for Li...6507 
 Linux Kernel 2.6...5279 
 Trees...1119 
 Максвелл 3...1051 
 William Gropp...990 
 Go Web ...963 
 Ethreal 3...930 
 Ethreal 4...917 
 Gary V.Vaughan-> Libtool...914 
 Ext4 FS...905 
 Clickhouse...901 
 Rodriguez 6...900 
 Ethreal 1...897 
 Steve Pate 1...886 
 C++ Patterns 3...864 
 Assembler...854 
 Ulrich Drepper...844 
 DevFS...788 
 MySQL & PosgreSQL...774 
 Стивенс 9...758 
 
  01.01.2024 : 3621733 посещений 

iakovlev.org

Базовые типы в Go

Идентификатор в go - это набор символов, букв, символа подчеркивания. Зарезервированные ключевые слова в go:
 break    default     func     interface     select
 case     defer       go       map           struct
 chan     else        goto     package       switch
 const    fallthrough if       range         type
 continue for         import   return        var
Зарезервированные идентификаторы:
 append         copy     int8       nil      true
 bool           delete   int16      panic    uint
 byte           error    int32      print    uint8
 cap            false    int64      println  uint16
 close          float32  iota       real     uint32
 complex        float64  len        recover  uint64
 complex64      imag     make       rune     uintptr
 complex128     int      new        string
Константы декларируются с помощью ключевого слова const. Переменные можно декларировать с помошью ключевого слова var или без:
 const limit = 512			// constant; type-compatible with any number
 const top uint16 = 1421                // constant; type: uint16
 start := -19				// variable; inferred type: int
 end := int64(9876543210)		// variable; type: int64
 var i int				// variable; value 0; type: int
 var debug = false			// variable; inferred type: bool
 checkResults := true			// variable; inferred type: bool
 stepSize := 1.5                        // variable; inferred type: float64
 acronym := "FOSS"			// variable; inferred type: string
В go два булевских типа true и false.
Бинарные логические операторы - ||(или) и &&(и).
Операторы сравнения - <, <=, ==, !=, >=, >
В Go 11 целочисленных типов, 5 знаковых, 5 беззнаковых, плюс указатель:
 byte                 Synonym for uint8
 int                  The int32 or int64 range depending on the implementation
 int8                 [−128, 127]  
 int16                [−32768, 32767]
 int32                [−2147483648, 2147483647]
 int64                [−9223372036854775808, 9223372036854775807]
 rune                 Synonym for int32
 uint                 The uint32 or uint64 range depending on the implementation
 uint8                [0, 255]
 uint16               [0, 65535]
 uint32               [0, 4294967295]
 uint64               [0, 18446744073709551615]
 uintptr              An unsigned integer capable of storing a pointer value (advanced)
В Go есть два типа чисел с плавающей точкой и два типа комплексных чисел:
 float32 	±3.40282346638528859811704183484516925440 х 10^38
 float64        ±1.797693134862315708145274237317043567981 х 10^308
 complex64      The real and imaginary parts are both of type float32.
 complex128 	The real and imaginary parts are both of type float64.
Например:

 f := 3.2e5                         // type: float64
 x := -7.3 - 8.9i                   // type: complex128 (literal)
 y := complex64(-18.3 + 8.9i)       // type: complex64 (conversion) 
 z := complex(f, 13.2)              // type: complex128 (construction)
 fmt.Println(x, real(y), imag(z))   // Prints: (-7.3-8.9i) -18.3 13.2
В следующем примере мы создадим локальный веб-сервер, который выведет в броузер страницу статистики:

Создадим базовую структуру:


 type statistics struct {
   numbers 	[]float64
   mean          float64
   median 	float64
 }
Главная функция запускает локальный веб-сервер на порту 9001:

 func main() {
   http.HandleFunc("/", homePage)
   if err := http.ListenAndServe(":9001", nil); err != nil {
     log.Fatal("failed to start server", err)
   }
 }
Текст программы:

 package main
 
 import (
     "fmt"
     "log"
     "net/http"
     "sort"
     "strconv"
     "strings"
 )
 
 const (
     pageTop    = `<!DOCTYPE HTML><html><head>
 <style>.error{color:#FF0000;}</style></head><title>Statistics</title>
 <body><h3>Statistics</h3>
 <p>Computes basic statistics for a given list of numbers</p>`
     form       = `<form action="/" method="POST">
 <label for="numbers">Numbers (comma or space-separated):</label><br />
 <input type="text" name="numbers" size="30"><br />
 <input type="submit" value="Calculate">
 </form>`
     pageBottom = `</body></html>`
     anError    = `<p class="error">%s</p>`
 )
 
 type statistics struct {
     numbers []float64
     mean    float64
     median  float64
 }
 
 func main() {
     http.HandleFunc("/", homePage)
     if err := http.ListenAndServe(":9001", nil); err != nil {
         log.Fatal("failed to start server", err)
     }
 }
 
 func homePage(writer http.ResponseWriter, request *http.Request) {
     err := request.ParseForm() // Must be called before writing response
     fmt.Fprint(writer, pageTop, form)
     if err != nil {
         fmt.Fprintf(writer, anError, err)
     } else {
         if numbers, message, ok := processRequest(request); ok {
             stats := getStats(numbers)
             fmt.Fprint(writer, formatStats(stats))
         } else if message != "" {
             fmt.Fprintf(writer, anError, message)
         }
     }
     fmt.Fprint(writer, pageBottom)
 }
 
 func processRequest(request *http.Request) ([]float64, string, bool) {
     var numbers []float64
     if slice, found := request.Form["numbers"]; found && len(slice) > 0 {
         text := strings.Replace(slice[0], ",", " ", -1)
         for _, field := range strings.Fields(text) {
             if x, err := strconv.ParseFloat(field, 64); err != nil {
                 return numbers, "'" + field + "' is invalid", false
             } else {
                 numbers = append(numbers, x)
             }
         }
     }
     if len(numbers) == 0 {
         return numbers, "", false // no data first time form is shown
     }
     return numbers, "", true
 }
 
 func formatStats(stats statistics) string {
     return fmt.Sprintf(`<table border="1">
 <tr><th colspan="2">Results</th></tr>
 <tr><td>Numbers</td><td>%v</td></tr>
 <tr><td>Count</td><td>%d</td></tr>
 <tr><td>Mean</td><td>%f</td></tr>
 <tr><td>Median</td><td>%f</td></tr>
 </table>`, stats.numbers, len(stats.numbers), stats.mean, stats.median)
 }
 
 func getStats(numbers []float64) (stats statistics) {
     stats.numbers = numbers
     sort.Float64s(stats.numbers)
     stats.mean = sum(numbers) / float64(len(numbers))
     stats.median = median(numbers)
     return stats
 }
 
 func sum(numbers []float64) (total float64) {
     for _, x := range numbers {
         total += x
     }
     return total
 }
 
 func median(numbers []float64) float64 {
     middle := len(numbers) / 2
     result := numbers[middle]
     if len(numbers)%2 == 0 {
         result = (result + numbers[middle-1]) / 2
     }
     return result
 }
Строки в Go - это последовательность байт в кодировке utf-8. На каждый символ в строке go используется 8 бит - в 2 раза меньше, чем в жабе или питоне. Строки можно инициализировать с помощью двойных кавычек либо одинарных обратных. Хотя строки в go immutable, они поддерживают конкатенацию с помощью оператора +=. Для строк возможны операции:
 s += t                      Appends string t to the end of string s
 s + t                       The concatenation of strings s and t 
 s[n]                        The raw byte at index position n (of type uint8) in s
 s[n:m]                      A string taken from s from index positions n to m - 1
 s[n:]                       A string taken from s from index positions n to len(s) - 1
 s[:m]                       A string taken from s from index positions 0 to m - 1 
 len(s)                      The number of bytes in string s
 len([]rune(s))[]            The number of characters in string s—use the faster utf8.
                             RuneCountInString() instead; see Table 3.10 (➤ 118)
 rune(s)                     Converts string s into a slice of Unicode code points        
 string(chars)               Converts a []rune or []int32 into a string; assumes that the
                             runes or int32s are Unicode code points
 []byte(s)                   Converts string s into a slice of raw bytes without copying;
                             there’s no guarantee that the bytes are valid UTF-8 			    
 string(bytes)               Converts a []byte or []uint8 into a string without copying;
                             there’s no guarantee that the bytes are valid UTF-8
 string(i)                   Converts i of any integer type into a string; assumes that i
                             is a Unicode code point
 strconv                     The string representation of i of type int and an error; e.g.,
 Itoa(i)                     if i is 65, it returns ("65", nil)
 
 fmt.Sprint(x)               The string representation of i of type int and an error; e.g.,
                             if i is 65, it returns ("65", nil);
Go поддерживает в строках срезы так же, как это делается в питоне. В следующем примере мы имеем строку, состоящую из слов, нужно найти первое и последнее слово в строке:

 line := "røde og gule sløjfer"
 i := strings.Index(line, " ")
 firstWord := line[:i]
 j := strings.LastIndex(line, " ")
 lastWord := line[j+1:]
 fmt.Println(firstWord, lastWord)
Пример работы строковой функции Split:

 names := "Niccolò•Noël•Geoffrey•Amélie••Turlough•José"
 fmt.Print("|")
 for _, name := range strings.Split(names, "•") {
 fmt.Printf("%s|", name)
 }
 fmt.Println()
Строки в Go имеют встроенные функции:

 strings.Contains(s, t)
 strings.Count(s, t)
 strings.EqualFold(s, t)
 strings.Fields(s)              The []string that results in splitting s on white space 
 strings.FieldsFunc(s, f)       The []string that results in splitting s at every character 
 				where f returns true
 strings.HasPrefix(s, t)
 strings.HasSuffix(s, t)
 strings.Index(s, t)            The index of the first occurrence of t in s
 strings.IndexAny(s, t)         The first index in s of any character that is in t
 strings.IndexFunc(s, f)        The index of the first character in s for which f returns true
 strings.IndexRune(s, char)
 strings.Join(xs, t)
 strings.LastIndex(s,strings.
 LastIndexAny(s, t)
 strings.LastIndexFunc(s, f)
 strings.Map(mf, t)
 strings.NewReader(s)
 strings.NewReplacer(...)
 strings.Repeat(s, i)
 strings.Replace(s,old, new, i)
 strings.Split(s, t)
 strings.SplitAfter(s, t)
 strings.SplitAfterN(s, t, i)
 strings.SplitN(s, t, i)
 strings.Title(s)
 strings.ToLower(s)
 strings.ToLowerSpecial(r, s)
 strings.ToTitle(s)
 strings.ToTitleSpecial(r, s)
 strings.ToUpper(s)
 strings.ToUpperSpecial(r, s)
 strings.Trim(s, t)
 strings.TrimFunc(s, f)
 strings.TrimLeft(s, t)
 strings.TrimLeftFunc(s, f)
 strings.TrimRight(s, t)
 strings.TrimRightFunc(s, f)
 strings.TrimSpace(s)
Пакет Regexp включает следующие функции:

 regexp.Match(p, b)             true and nil if p matches b of type []byte
 regexp.Match-Reader(p, r)      true and nil if p matches the text read by r of type io.RuneReader
 regexp.Match-String(p, s)      true and nil if p matches s
 regexp.QuoteMeta(s)            A string with all regexp metacharacters safely quoted
 regexp.Compile(p)              A *regexp.Regexp and nil if p compiles successfully
 regexp.Compile-POSIX(p)        A *regexp.Regexp and nil if p compiles successfully; 
 regexp.Must-Compile(p)         A *regexp.Regexp if p compiles successfully, otherwise panics
 rx.Find(b)
 rx.FindAll(b, n)
 rx.FindAllIndex(b, n)
 rx.FindAllString(s, n)
 rx.FindAllString-
 Index(s, n)
 rx.FindAllStringSubmatch(s, n)
 rx.FindAllStringSubmatchIndex(s, n)
 rx.FindAllSubmatch(b, n)
 rx.FindAllSubmatchIndex(b, n)
 rx.FindIndex(b)
 rx.FindReaderIndex(r)
 rx.FindReaderSubmatchIndex(r)
 rx.FindString(s)
 rx.FindStringIndex(s)
 rx.FindStringSubmatch(s)
 rx.FindStringSubmatchIndex(s)
 rx.Match(b)
 rx.MatchReader(r)
 rx.MatchString(s)
 rx.NumSubexp()
 rx.ReplaceAll(b, br)
 rx.ReplaceAllFunc(b, f)
 rx.ReplaceAllLiteral(b, br)
В следующем примере приведены три варианта конкатенации строк - от самого медленного до самого быстрого

 Пример 1:
 for i := 0; i < b.N; i++ {
     s1 = s1 + s2
 }   
 
 Пример 2:
 s3 := []byte(s1)
 for i := 0; i < b.N; i++ {
     s3 = append(s3, s2...)
 }   
 s1 = string(s3)
 
 Пример 3:
 var buffer bytes.Buffer
 for i := 0; i < b.N; i++ {
     buffer.WriteString(s2)
 }
 s1 := buffer.String()
 
В следующем примере программа читает плэйлист-файл с расширением .m3u и выводит эквивалентный файл с расширением .pls. Файл .m3u обычно имеет следующий формат:
 #EXTM3U
 #EXTINF:315,David Bowie - Space Oddity
 Music/David Bowie/Singles 1/01-Space Oddity.ogg
 #EXTINF:-1,David Bowie - Changes
 Music/David Bowie/Singles 1/02-Changes.ogg
 ...
Здесь присутствует длина трека в секундах, название и путь. Эквивалентный файл .pls выглядит так:
 [playlist]
 File1=Music/David Bowie/Singles 1/01-Space Oddity.ogg
 Title1=David Bowie - Space Oddity
 Length1=315
 File2=Music/David Bowie/Singles 1/02-Changes.ogg
 Title2=David Bowie - Changes
 Length2=-1
 ...
Код программы:

 
 package main
 
 import (
     "fmt"
     "io/ioutil"
     "log"
     "os"
     "path/filepath"
     "strconv"
     "strings"
 )
 
 type Song struct {
     Title    string
     Filename string
     Seconds  int
 }
 
 func main() {
     if len(os.Args) == 1 || !strings.HasSuffix(os.Args[1], ".m3u") {
         fmt.Printf("usage: %s \n", filepath.Base(os.Args[0]))
         os.Exit(1)
     }
 
     if rawBytes, err := ioutil.ReadFile(os.Args[1]); err != nil {
         log.Fatal(err)
     } else {
         songs := readM3uPlaylist(string(rawBytes))
         writePlsPlaylist(songs)
     }
 }
 
 func readM3uPlaylist(data string) (songs []Song) {
     var song Song
     for _, line := range strings.Split(data, "\n") {
         line = strings.TrimSpace(line)
         if line == "" || strings.HasPrefix(line, "#EXTM3U") {
             continue
         }
         if strings.HasPrefix(line, "#EXTINF:") {
             song.Title, song.Seconds = parseExtinfLine(line)
         } else {
             song.Filename = strings.Map(mapPlatformDirSeparator, line)
         }
         if song.Filename != "" && song.Title != "" && song.Seconds != 0 {
             songs = append(songs, song)
             song = Song{}
         }
     }
     return songs
 }
 
 func parseExtinfLine(line string) (title string, seconds int) {
     if i := strings.IndexAny(line, "-0123456789"); i > -1 {
         const separator = ","
         line = line[i:]
         if j := strings.Index(line, separator); j > -1 {
             title = line[j+len(separator):]
             var err error
             if seconds, err = strconv.Atoi(line[:j]); err != nil {
                 log.Printf("failed to read the duration for '%s': %v\n",
                     title, err)
                 seconds = -1
             }
         }
     }
     return title, seconds
 }
 
 func mapPlatformDirSeparator(char rune) rune {
     if char == '/' || char == '\\' {
         return filepath.Separator
     }
     return char
 }
 
 func writePlsPlaylist(songs []Song) {
     fmt.Println("[playlist]")
     for i, song := range songs {
         i++
         fmt.Printf("File%d=%s\n", i, song.Filename)
         fmt.Printf("Title%d=%s\n", i, song.Title)
         fmt.Printf("Length%d=%d\n", i, song.Seconds)
     }
     fmt.Printf("NumberOfEntries=%d\nVersion=2\n", len(songs))
 }

Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье