Calvert's murmur

Golang 基本型別、運算子和型別轉換

2019-11-05

約 6612 字 / 需 36 分鐘閱讀

原文:CalliCoderGolang Basic Types, Operators and Type Conversion

Go 是靜態型別的程式語言。Golang 中的每個變數都有關聯的型別。

資料型別會對一組相關的資料集進行分類。它們定義了資料如何儲存在記憶體中、特定資料型別的變數可能儲存的值以及可以對其執行的運算。

Golang 具有多種內建的資料型別,用於表示常見的值,如數字、布林值、字串等。在本文中,我們將逐一介紹這些基本資料型別,並了解它們的工作原理。

數字型別

數字型別用於表示數字。可以分為整數和浮點數型別:

1. 整數

整數用於儲存整數。Go 具有多種大小不一的內建整數型別,用於儲存有號數和無號數:

有號數
型別 大小 範圍
int8 8 bits -128 到 127
int16 16 bits -215 到 215 -1
int32 32 bits -231 到 231 -1
int64 64 bits -263 到 263 -1
int 取決於平台 取決於平台

泛型 int 型別的大小取決於平台。在 32 位元系統上,它的大小為 32 位元,在 64 位元系統上,它的大小為 64 位元。

無號數
型別 大小 範圍
uint8 8 bits 0 到 255
uint16 16 bits 0 到 216 -1
uint32 32 bits 0 到 232 -1
uint64 64 bits 0 到 264 -1
uint 取決於平台 取決於平台

uint 型別的大小取決於平台。在 32 位元系統上,它的大小為 32 位元,在 64 位元系統上,它的大小為 64 位元。

使用整數值時,除非有充分的理由使用有號數或無號數,否則應該始終使用 int 資料型別。

在 Golang 中,你可以使用前綴 0 來宣告八進制數字,以及使用前綴 0x0X 來宣告十六進制數字。以下是整數型別的完整範例:

package main

import "fmt"

func main() {
	var myInt8 int8 = 97

	/*
	  When you don't declare any type explicitly, the type inferred is `int`
	  (The default type for integers)
	*/
	var myInt = 1200

	var myUint uint = 500

	var myHexNumber = 0xFF  // Use prefix '0x' or '0X' for declaring hexadecimal numbers
	var myOctalNumber = 034 // Use prefix '0' for declaring octal numbers

	fmt.Printf("%d, %d, %d, %#x, %#o\n", myInt8, myInt, myUint, myHexNumber, myOctalNumber)
}
# Output
97, 1200, 500, 0xff, 034
整數型別別名

Golang 還有另外兩個稱為 byterune 的整數型別,分別是 uint8int32 資料型別的別名。

別名 型別
byte uint8
rune int32

在 Go 語言中,byterune 資料型別用於區分字元和整數值。

Golang 沒有 char 資料型別。它使用 byterune 來表示字元值。byte 資料型別用於表示 ASCII 字元,以及 rune 資料型別用於表示以 UTF-8 格式編碼的一組更廣泛的 Unicode 字元。

要在 Golang 中表示字元可以像這樣透過單引號將它們括起來:'A'

字元值的預設型別是 rune。也就是說,當宣告帶有字元值的變數而未明確指定型別時,則 Go 會將型別推斷為 rune

var firstLetter = 'A' // Type inferred as `rune` (Default type for character values)

你可以透過明確地指定型別來建立 byte 變數:

var lastLetter byte = 'Z'

byterune 資料型別本質上都是整數。舉例來說,具有值 'a'byte 變數會轉換為整數 97。

相同的,具有 Unicode 值 '♥'rune 變數會轉換為相應的 Unicode 代碼點 U + 2665,其中 U+ 代表 Unicode,且數字是十六進制,本質上是整數。

package main

import "fmt"

func main() {
	var myByte byte = 'a'
	var myRune rune = '♥'

	fmt.Printf("%c = %d and %c = %U\n", myByte, myByte, myRune, myRune)
}
# Output
a = 97 and ♥ = U+2665

在上面的範例中,我以字元和十進制格式印出變數 myByte,並以字元和 Unicode 格式印出變數 myRune

2. 浮點數型別

浮點數型別用於儲存帶小數部分的數字(如:1.24、4.50000)。Go 有兩種浮點數型別:float32float64

  • float32 在記憶體中佔用 32 位元,並以單精度浮點數格式儲存數值。
  • float64 在記憶體中佔用 64 位元,並以雙精度浮點數格式儲存數值。

浮點數的預設型別是 float64。因此,當你使用初始值初始化浮點數變數而未明確指定型別時,編譯器會將型別推斷為 float64

var a = 9715.635   // Type inferred as `float64` (the default type for floating-point numbers)

數字型別的運算

Go 提供了多種用於對數字型別執行運算的運算子:

  • 算術運算子:+, -, *, /, %
  • 比較運算子:==, !=, <, >, <=, >=
  • 位元運算子:&, |, ^, <<, >>
  • 遞增和遞減運算子:++, --
  • 賦值運算子:+=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^=

以下是上述一些運算子的範例:

package main

import (
	"fmt"
	"math"
)

func main() {
	var a, b = 4, 5
	var res1 = (a + b) * (a + b) / 2 // Arithmetic operations

	a++ // Increment a by 1

	b += 10 // Increment b by 10

	var res2 = a ^ b // Bitwise XOR

	var r = 3.5
	var res3 = math.Pi * r * r // Operations on floating-point type

	fmt.Printf("res1 : %v, res2 : %v, res3 : %v\n", res1, res2, res3)
}
# Output
res1 : 40, res2 : 10, res3 : 38.48451000647496

布林值

Go 提供了一種稱為 bool 的資料型別來儲存布林值。它有兩個可能的值:truefalse

var myBoolean = true
var anotherBoolean bool = false

布林值型別的運算

你可以對布林值使用以下運算子:

邏輯運算子:

  • &&(與,and)
  • ||(或,or)
  • ! (否定)

相等和不相等: ==, !=

運算子 &&|| 遵循短路規則。也就是說,在表達式 E1 && E2 中,如果 E1 的評估結果為 false,則不會評估 E2。相同的,在表達式 E1 || E2 中,如果 E1 的評估結果為 true,則不會評估 E2

以下是布林值型別的範例:

package main

import "fmt"

func main() {
	var truth = 3 <= 5
	var falsehood = 10 != 10

	// Short Circuiting
	var res1 = 10 > 20 && 5 == 5     // Second operand is not evaluated since first evaluates to false
	var res2 = 2*2 == 4 || 10%3 == 0 // Second operand is not evaluated since first evaluates to true

	fmt.Println(truth, falsehood, res1, res2)
}
# Output
true false false true

複數

複數是 Golang 中的基本型別之一。Go 有兩種不同大小的複數型別:

  • complex64:實部和虛部都是 float32 型別。
  • complex128:實部和虛部都是 float64 型別。

Golang 中複數的預設型別是 complex128。你可以像這樣建立一個複數:

var x = 5 + 7i  // Type inferred as `complex128`

Go 還提供了一個名為 complex 的內建函數,用於建立複數。如果你要使用變數而不是文字來建立複數,則需要使用 complex 函數:

var a = 3.57
var b = 6.23

// var c = a + bi won't work. Create the complex number like this -
var c = complex(a, b)

要注意的是,複數的實部和虛部都必須是相同的浮點數型別。如果你嘗試建立具有不同實部和虛部型別的複數,則編譯器將拋出錯誤:

var a float32 = 4.92
var b float64 = 7.38

/*
   The Following statement Won't compile.
   (Both real and imaginary parts must be of the same floating-point type)
*/
var c = complex(a, b)  // Compiler Error

複數型別的運算

你可以對複數執行算術運算,如加、減、乘和除:

package main

import "fmt"

func main() {
	var a = 3 + 5i
	var b = 2 + 4i

	var res1 = a + b
	var res2 = a - b
	var res3 = a * b
	var res4 = a / b

	fmt.Println(res1, res2, res3, res4)
}
# Output
(5+9i) (1+1i) (-14+22i) (1.3-0.1i)

字串

在 Go 中,字串是字元組序列。

Golang 中的字串可以使用如 "Hello World" 中的雙引號宣告,也可以使用如 `Hello World` 中的反引號宣告。

// Normal String (Can not contain newlines, and can have escape characters like `\n`, `\t` etc)
var name = "Steve Jobs"

// Raw String (Can span multiple lines. Escape characters are not interpreted)
var bio = `Steve Jobs was an American entrepreneur and inventor.
           He was the CEO and co-founder of Apple Inc.`

用雙引號括起來的字串不能包含換行,但可以包含跳脫字元,如 \n\t 等。在雙引號字串中,會用換行字元替換 \n 字元,並用 tab 空格替換 \t 字元,依此類推。

反引號內包含的字串是原始字串。它們可以跨越多行。此外,跳脫字元在原始字串中沒有任何特殊含義。

package main

import "fmt"

func main() {
	var website = "\thttps://www.callicoder.com\t\n"

	var siteDescription = `\t\tCalliCoder is a programming blog where you can find
                           practical guides and tutorials on programming languages,
                           web development, and desktop app development.\t\n`

    fmt.Println(website, siteDescription)
}
# Output
        https://www.callicoder.com
 \t\tCalliCoder is a programming blog where you can find
                           practical guides and tutorials on programming languages,
                           web development, and desktop app development.\t\n

以上就是本文關於字串的全部內容。但還有很多關於字串的知識要了解,包括字串索引、處理 Unicode 字元以及執行各種操作如字串連接、分離等。我們將在以後的文章中了解它們。

型別轉換

Golang 有個強型別系統。它不允許你在表達式中混合數字型別。舉例來說,你不能將 int 變數加到 float64 變數中,也不能將 int 變數加到 int64 變數中。你甚至無法在混合型別之間執行分派:

var a int64 = 4
var b int = a // Compiler Error (Cannot use a (type in64) as type int in assignment)

var c int = 500

var result = a + c // Compiler Error (Invalid Operation: mismatched types int64 and int)

與 C、C++ 和 Java 等其他靜態型別語言不同,Go 不提供任何隱式型別轉換。要了解為何採用這種方式設計 Go,請查看下一篇文章:在 Golang 中使用常數

好吧!即使它們是數字型別,我們也不能對兩種不同型別進行加、減、比較或任何類型的運算。但如果我們需要執行這樣的運算該怎麼辦?

嗯,你需要將變數明確地轉換為目標型別:

var a int64 = 4
var b int = int(a) // Explicit Type Conversion

var c float64 = 6.5

// Explicit Type Conversion
var result = float64(b) + c // Works

一般將值 v 轉換為型別 T 的語法是 T(v)。這裡有幾個範例:

var myInt int = 65
var myUint uint = uint(myInt)
var myFloat float64 = float64(myInt)

結論

在本文中,你了解了 Golang 提供的各種基本資料型別、可以對這些型別執行的操作,以及如何將一種型別轉換為另一種型別。

Tags: Golang