One place for hosting & domains

      Конвертация типов данных в Go


      Введение

      В Go типы данных используются для классификации одного конкретного типа данных, определяя значения, которые вы можете присвоить для этого типа, а также операции, которые вы можете с ними совершать. При программировании бывают случаи, когда вам требуется конвертировать значения между типами, чтобы манипулировать значениями разным образом. Например, вам может потребоваться выполнить конкатенацию числовых значений со строками или представить десятичные значения для чисел, инициализированных как целые числа. Генерируемые пользователями данные часто автоматически сохраняются в виде строкового типа, даже если они состоят из чисел; для выполнения математических операций с вводимыми данными вам нужно будет преобразовывать строки в числовой тип данных.

      Поскольку Go — это статически типизированный язык, типы данных привязываются к переменным, а не к значениям. Это означает, что если вы задаете переменную типа int, она может быть только типа int; вы не можете сохранить в ней string, не преобразовав тип данных переменной. Статичный характер типов данных в Go делает еще более важным необходимость знакомства со способами конвертации типов.

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

      Конвертация числовых типов

      В Go существует несколько числовых типов. В первую очередь они делятся на два основных типа: целые числа и числа с плавающей точкой.

      Существует множество ситуаций, когда вам может потребоваться преобразовать один числовой тип в другой. Конвертация между числовыми типами разных размеров может помочь оптимизировать производительность для конкретных видов системной архитектуры. Если у вас есть целое число из другой части кода и вы хотите выполнить деление на это число, вы можете захотеть изменить тип с integer на float, чтобы сохранить точность операции. Кроме того, работа с временными интервалами обычно подразумевает преобразование целых чисел. Чтобы устранить подобные проблемы, в Go есть встроенная конверсия типов для большинства численных типов.

      Конвертация между целыми числами

      В Go есть несколько целочисленных типов данных на выбор. Когда использовать тот или иной тип — это больше вопрос производительности; однако существуют ситуации, когда вам нужно будет преобразовывать один целочисленный тип в другой. Например, Go иногда автоматически генерирует числовые значения типа int, что может не соответствовать значениям вашего ввода. Если вы ввели значение int64, вы не сможете использовать числа int и int64 в одном математическом выражении, пока не будет выполнено преобразование к одном типу данных.

      Предположим, что у вас есть int8, и вам нужно преобразовать его в int32. Вы можете сделать это, обернув его в преобразование типа int32():

      var index int8 = 15
      
      var bigIndex int32
      
      bigIndex = int32(index)
      
      fmt.Println(bigIndex)
      

      Output

      15

      Этот блок кода определяет index как тип данных int8 и bigIndex как тип данных int32. Чтобы сохранить значение index в bigIndex, он преобразовывает тип данных в int32. Это делается посредством оборачивания конверсии в int32() вокруг переменной index.

      Чтобы проверить ваши типы данных, вы можете использовать fmt.Printf и %T со следующим синтаксисом:

      fmt.Printf("index data type:    %Tn", index)
      fmt.Printf("bigIndex data type: %Tn", bigIndex)
      

      Output

      index data type: int8 bigIndex data type: int32

      Поскольку здесь используется %T, оператор вывода выводит тип переменной, а не фактическое значение переменной. Таким образом вы можете подтвердить выполнение преобразования типа данных.

      Также вы можете преобразовывать целочисленный тип с большим количеством бит в целочисленный тип с меньшим количеством бит:

      var big int64 = 64
      
      var little int8
      
      little = int8(big)
      
      fmt.Println(little)
      

      Output

      64

      Обратите внимание, что при преобразовании целых чисел может быть превышено максимальное значение для данного типа данных и выполняется перенос:

      var big int64 = 129
      var little = int8(big)
      fmt.Println(little)
      

      Output

      -127

      Перенос происходит, когда значение преобразовывается в тип данных, который слишком мал, чтобы хранить его. В предыдущем примере 8-битный тип данных int8 не имеет достаточно места для хранения 64-битной переменной big. Всегда следует учитывать, что при преобразовании из большего типа данных в меньший тип данных вы можете случайно обрезать данные.

      Конвертация целых чисел в числа с плавающей точкой

      Преобразование целых чисел в числа с плавающей точкой похоже на преобразование одного целочисленного типа в другой. Вы можете использовать встроенную конверсию типов, обернув float64()​​​ или float32() вокруг целого числа:

      var x int64 = 57
      
      var y float64 = float64(x)
      
      fmt.Printf("%.2fn", y)
      

      Output

      57.00

      Этот код объявляет переменную x типа int64 и инициализирует ее со значением 57.

      var x int64 = 57
      

      Использование обертки float64() для конверсии x позволит преобразовывать значение 57 в значение с плавающей точкой 57.00.

      var y float64 = float64(x)
      

      %.2f сообщает fmt.Printf, что необходимо выводить число с двумя знаками после разделителя.

      Также вы можете использовать этот процесс для переменной. Следующий код объявляет f​​​ равной 57, а затем выводит новое число с плавающей точкой:

      var f float64 = 57
      fmt.Printf("%.2fn", f)
      

      Output

      57.00

      Используя float32() или float64()​​​, вы можете преобразовывать целые числа в числа с плавающей точкой. Далее вы научитесь преобразовывать тип float в int.

      Преобразование чисел с плавающей точкой в целые числа

      Go может преобразовывать тип float в int, но программа в этом случае теряет точность числа с плавающей точкой.

      Оборачивание float в int() или один из архитектурно-зависимых типов данных работает тем же самым образом, который вы использовали для преобразования одного целочисленного типа в другой. Вы можете добавить число с плавающей точкой внутри скобок, чтобы преобразовывать его в целое число:

      var f float64 = 390.8
      var i int = int(f)
      
      fmt.Printf("f = %.2fn", f)
      fmt.Printf("i = %dn", i)
      

      Output

      f = 390.80 i = 390

      Этот синтаксис преобразовывает число с типом float 390.8 в целое число 390, отбрасывая все, что стоит после десятичного разделителя.

      Также вы можете использовать такой способ с переменными. Код ниже объявляет переменную b, равную 125.0, и переменную c, равную 390.8, а затем выводит их как целые числа. Краткое объявление переменных (:=) сокращает синтаксис:

      b := 125.0
      c := 390.8
      
      fmt.Println(int(b))
      fmt.Println(int(c))
      

      Output

      125 390

      При преобразовании float в целое число с типом int() Go обрезает часть с десятичными дробями для получения целого числа. Обратите внимание, что даже если вы захотите округлить 390.8 до 391, Go не сможет сделать это с типом int(). Вместо этого будет отброшена часть после десятичного разделителя.

      Числа, конвертируемые с помощью деления

      При делении целочисленных типов в Go результат также будет целым числом, а модуль, или остаток, отбрасывается:

      a := 5 / 2
      fmt.Println(a)
      

      Output

      2

      Если при делении используются числовые типы с плавающей точкой, тогда все остальные типы будут автоматически объявляться как числа с плавающей точкой:

          a := 5.0 / 2
          fmt.Println(a)
      

      Output

      2.5

      Здесь число типа float 5.0 делится на целое число 2, а ответ 2.5 — это число с плавающей точкой, сохраняющее точность деления.

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

      Конвертация строк

      Строка — это последовательность одного или нескольких символов (букв, чисел или символов). Строки очень часто используются в компьютерных программах, и вам может потребоваться преобразовать строки в числа или числа в строки, особенно если вы используете данные, генерируемые пользователем.

      Конвертация чисел в строки

      Вы можете преобразовывать числа в строки, используя метод strconv.Itoa из пакета strconv стандартной библиотеки Go. Если вы передадите число или переменную в скобках метода, это числовое значение будет преобразовано в строковое значение.

      Сначала давайте рассмотрим преобразование целых чисел. Чтобы преобразовывать целое число 12 в строковое значение, вы можете передать 12 в метод strconv.Itoa:

      package main
      
      import (
          "fmt"
          "strconv"
      )
      
      func main() {
          a := strconv.Itoa(12)
          fmt.Printf("%qn", a)
      }
      

      При запуске этой программы вы получите следующий вывод:

      Output

      "12"

      Кавычки вокруг числа 12 означают, что число больше не является числовым значением, а хранит строку.

      Вы использовали оператор := для декларирования новой переменной с именем а и присвоения значения, возвращаемого функцией strconv.Itoa(). В данном случае вы присвоили значение 12 вашей переменной. Также вы использовали %q в функции fmt.Printf, чтобы указать функции процитировать предоставленную строку.

      Используя переменные, вы начинаете понимать, насколько практично преобразовывать целые числа в строки. Скажем, вы хотите отслеживать ежедневный прогресс пользователя в программировании и указывать, сколько строк кода он написал на данный момент. Вы можете захотеть демонстрировать эти данные пользователю и выводить строку и целое число одновременно:

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          user := "Sammy"
          lines := 50
      
          fmt.Println("Congratulations, " + user + "! You just wrote " + lines + " lines of code.")
      }
      

      При запуске этого кода вы получите следующую ошибку:

      Output

      invalid operation: ("Congratulations, " + user + "! You just wrote ") + lines (mismatched types string and int)

      Вы не можете выполнять конкатенацию строк и целых чисел в Go, поэтому вам нужно будет преобразовывать переменную lines в строку:

      package main
      
      import (
          "fmt"
          "strconv"
      )
      
      func main() {
          user := "Sammy"
          lines := 50
      
          fmt.Println("Congratulations, " + user + "! You just wrote " + strconv.Itoa(lines) + " lines of code.")
      }
      

      Теперь, когда вы запускаете код, вы получите следующий вывод, содержащий поздравление пользователя с достигнутым прогрессом:

      Output

      Congratulations, Sammy! You just wrote 50 lines of code.

      Если вы хотите преобразовать число с плавающей точкой в строку, вместо целого числа вам следует использовать аналогичные шаги и формат. При передаче типа float в метод fmt.Sprint из пакета fmt стандартной библиотеки Go методу вернется строковое значение типа float. Вы можете использовать непосредственно число с плавающей точкой или переменную:

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          fmt.Println(fmt.Sprint(421.034))
      
          f := 5524.53
          fmt.Println(fmt.Sprint(f))
      }
      

      Output

      421.034 5524.53

      Вы можете выполнить тест, чтобы убедиться, что все работает правильно, выполнив конкатенацию со строкой:

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          f := 5524.53
          fmt.Println("Sammy has " + fmt.Sprint(f) + " points.")
      }
      

      Output

      Sammy has 5524.53 points.

      Вы можете быть уверены, что преобразование типа float в string было выполнено успешно, поскольку конкатенация выполняется без ошибок.

      Конвертация строк в числа

      Строки можно преобразовывать в цифры, используя пакет strconv в стандартной библиотеке Go. Пакет strconv содержит функции для преобразования для типов integer и float. Это очень распространенная операция при получении ввода от пользователя. Например, если у вас есть программа, которая запрашивает возраст пользователя, и когда пользователь вводит данные, они сохраняются как string. Затем вам нужно будет преобразовать их в int, чтобы выполнять математические операции.

      Если строка не имеет десятичных дробей, вы можете преобразовать ее в целое число, используя функцию strconv.Atoi. Если вы знаете, что будете использовать число типа float, вам следует использовать strconv.ParseFloat.

      Давайте используем в качестве примера пользователя Sammy, отслеживающего количество строк, которое он пишет каждый день. Возможно, вам нужно будет выполнять математические манипуляции, чтобы предоставить пользователю более интересные данные, но эти значения хранятся в строках:

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          lines_yesterday := "50"
          lines_today := "108"
      
          lines_more := lines_today - lines_yesterday
      
          fmt.Println(lines_more)
      }
      

      Output

      invalid operation: lines_today - lines_yesterday (operator - not defined on string)

      Поскольку два числовых значения хранятся в строках, вы получили ошибку. Операнд - для вычета не является действительным оператором для строковых значений.

      Измените код, включив метод strconv.Atoi(), который будет преобразовывать строки в числа, что позволит выполнять математические операции со значениями, которые были строками. Поскольку при преобразовании строки в целое число может произойти сбой, вы должны убедиться в отсутствии ошибок. Вы можете использовать оператор if, чтобы проверить, что конвертация была выполнена успешно.

      package main
      
      import (
          "fmt"
          "log"
          "strconv"
      )
      
      func main() {
          lines_yesterday := "50"
          lines_today := "108"
      
          yesterday, err := strconv.Atoi(lines_yesterday)
          if err != nil {
              log.Fatal(err)
          }
      
          today, err := strconv.Atoi(lines_today)
          if err != nil {
              log.Fatal(err)
          }
          lines_more := today - yesterday
      
          fmt.Println(lines_more)
      }
      

      Поскольку строка может содержать не только числовые значения, метод strconv.Atoi() может возвращать как преобразованный тип, так и потенциальную ошибку. При преобразовании lines_yesterday с помощью функции strconv.Atoi вы должны проверить возвращаемое значение err, чтобы убедиться, что значение преобразовано. Если err не nil, это означает, что strconv.Atoi удалось успешно преобразовать значение строки в целое число. В данном примере вы использовали оператор if для проверки на ошибки, и если возвращена ошибка, вы использовали log.Fatal для сохранения ошибки и выхода из программы.

      При запуске предыдущего кода вы получите следующий вывод:

      Output

      58

      Теперь попробуйте преобразовать строку, которая не является числом:

      package main
      
      import (
          "fmt"
          "strconv"
      )
      
      func main() {
          a := "not a number"
          b, err := strconv.Atoi(a)
          fmt.Println(b)
          fmt.Println(err)
      }
      

      Вы получите следующую ошибку:

      Output

      0 strconv.Atoi: parsing "not a number": invalid syntax

      Поскольку b была объявлена, но strconv.Atoi не удалось выполнить конвертацию, значение не было присвоено b. Обратите внимание, что b имеет значение 0. Это объясняется тем, что Go имеет значения по умолчанию, которые называются нулевыми значениями. strconv.Atoi возвращает ошибку с описанием того, почему не удалось выполнить конвертацию строки.

      Конвертация строк и байтов

      Строки в Go хранятся как срезы байтов. В Go вы можете преобразовывать срезы байтов в строки и обратно, используя соответствующую конвертацию в []byte() и string():

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          a := "my string"
      
          b := []byte(a)
      
          c := string(b)
      
          fmt.Println(a)
      
          fmt.Println(b)
      
          fmt.Println(c)
      }
      

      Здесь вы сохранили строковое значение в a, а затем преобразовали его в срез байтов b, после чего преобразовали срез байтов обратно в строку с именем c. Затем вы выводите а, b и с на экран:

      Output

      my string [109 121 32 115 116 114 105 110 103] my string

      Первая строка вывода — это первоначальная строка my string. Вторая строка вывода — это срез байтов, составляющих первоначальную строку. Третья строка показывает, что срез байтов можно безопасно преобразовывать обратно в строку и вывести на экран.

      Заключение

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

      Если вы хотите более подробно познакомиться с типами данных в Go, ознакомьтесь с нашей статьей Знакомство с типами данных в Go.



      Source link