GO語言數據類型及常量

目錄

  1. GO語言數據類型
  2. 格式化輸出
  3. 數據類型轉換
  4. 常量

Go 語言中的程序實體包括變量、常量、函數、結構體和接口。在 文章中可以瞭解變量相關的內容。

Go語言是靜態類型的編程語言,所以我們在聲明變量或常量的時候,都需要指定它們的類型,或者給予足夠的信息,這樣才可以讓 Go 語言能夠推導出它們的類型。。


1、GO語言數據類型

複合數據類型這裡不詳細贅述,後續會有單獨的文章詳細講解。

GO語言數據類型及常量

GO語言數據類型

1.1 整型

有符號整型: int8 int16 int32 int64 int

無符號整型:uint8 uint16 uint32 uint64 uint

其中uint8就是byte型,int16對應C語言中的short型,int64對應C語言中的long型

GO語言數據類型及常量

整型

GO語言中還有一些其他的數字類型,如下圖:

GO語言數據類型及常量

其他數字類型

1.2 浮點型

Go語言提供了兩種精度的複數類型:complex64和complex128,分別對應float32和float64兩種浮點數精度。內置的complex函數用於構建複數,內建的real和imag函數分別返回複數的實部和虛部。

GO語言數據類型及常量

浮點型

複數也可以用==和!=進行相等比較。只有兩個複數的實部和虛部都相等的時候它們才是相等的。 math/cmplx包提供了複數處理的許多函數,例如求複數的平方根函數和求冪函數。

z := x + yi
x = real(z)
y = imag(z)

1.3 布爾型

布爾型只有 true 和 false 兩個值 ,並且布爾型無法參與計算,也不能和其他類型相互轉換。

1.4 字符串類型

一個字符串是一個不可改變的字節序列。字符串可以包含任意的數據,包括byte值0,但是通常是用來包 含人類可讀的文本。文本字符串通常被解釋為採用UTF8編碼的Unicode碼點(rune)序列。

其中+操作符將兩個字符串鏈接構造一個新字符串。

字符串可以用==和

字符串值也可以用字符串面值方式編寫,只要將一系列字節序列包含在雙引號即可。

字符串的值是不可變的:一個字符串包含的字節序列永遠不會被改變,當然我們也可以給一個字符串變 量分配一個新字符串值。

s := "left foot"
t := s
s += ", right foot"

這並不會導致原始的字符串值被改變,但是變量s將因為+=語句持有一個新的字符串值,但是t依然是包含原先的字符串值。

1.5 字符

字符串中的每一個元素叫“字符”,定義字符使用單引號'。GO語言中的字符有兩種:

  1. byte型:uint8的別名,代表一個ASCII碼字符
  2. rune型:int32的別名,代表一個UTF-8字符 ,當需要處理中文等unicode字符集時需要用到rune類型。
var a byte = 'a'
var r rune = '中'

2、格式化輸出

golang 的fmt 包實現了格式化I/O函數,類似於C的 printf 和 scanf。格式化verb('verb')源自C語言但更簡單。

2.1 通用

變量值和類型格式化

%v 值的默認格式表示。當輸出結構體時,擴展標誌(%+v)會添加字段名
%#v 值的Go語法表示
%T 值的類型的Go語法表示
%% 百分號

2.2 布爾值

%t 單詞true或false 

2.3 整數

%b 表示為二進制
%c 該值對應的unicode碼值
%d 表示為十進制
%o 表示為八進制
%q 該值對應的單引號括起來的go語法字符字面值,必要時會採用安全的轉義表示
%x 表示為十六進制,使用a-f
%X 表示為十六進制,使用A-F
%U 表示為Unicode格式:U+1234,等價於"U+%04X"

2.4 浮點數、複數的兩個組分

%b 無小數部分、二進制指數的科學計數法,如-123456p-78;參strconv.FormatFloat 
%e 科學計數法,如-1234.456e+78
%E 科學計數法,如-1234.456E+78
%f 有小數部分但無指數部分,如123.456
%F 等價於%f
%g 根據實際情況採用%e或%f格式(以獲得更簡潔、準確的輸出)
%G 根據實際情況採用%E或%F格式(以獲得更簡潔、準確的輸出)

2.5 字符串和[]byte

%s 直接輸出字符串或者[]byte %q 該值對應的雙引號括起來的go語法字符串字面值,必要時會採用安全的轉義表示 

%x 每個字節用兩字符十六進制數表示(使用a-f)
%X 每個字節用兩字符十六進制數表示(使用A-F)

2.6 指針

%p 表示為十六進制,並加上前導的0x

沒有 %u。整數如果是無符號類型自然輸出也是無符號的。類似的,也沒有必要指定操作數的尺寸(int8,int64)。

寬度通過一個緊跟在百分號後面的十進制數指定,如果未指定寬度,則表示值時除必需之外不作填充。精度通過(可能有的)寬度後跟點號後跟的十進制數指定。如果未指定精度,會使用默認精度;如果點號後沒有跟數字,表示精度為0。舉例如下:

%f: 默認寬度,默認精度
%9f 寬度9,默認精度
%.2f 默認寬度,精度2
%9.2f 寬度9,精度2
%9.f 寬度9,精度0

2.7 其它flag

+ 總是輸出數值的正負號;對%q(%+q)會生成全部是ASCII字符的輸出(通過轉義); 

- 在輸出右邊填充空白而不是默認的左邊(即從默認的右對齊切換為左對齊);
# 切換格式:
八進制數前加0(%#o),十六進制數前加0x(%#x)或0X(%#X),指針去掉前面的0x(%#p);
對%q(%#q),如果strconv.CanBackquote返回真會輸出反引號括起來的未轉義字符串;
對%U(%#U),如果字符是可打印的,會在輸出Unicode格式、空格、單引號括起來的go字面值;
' ' 對數值,正數前加空格而負數前加負號;
對字符串採用%x或%X時(% x或% X)會給各打印的字節之間加空格;
0 使用0而不是空格填充,對於數值類型會把填充的0放在正負號後面;

3、數據類型轉換

類型轉換用於將一種數據類型的變量轉換為另外一種類型的變量。Go 語言類型轉換基本格式如下:

type_name(expression)
  • type_name 為類型,expression 為表達式,表達式包括變量、數值、函數返回值等。
  • 數據類型發生轉換時需要考慮兩種類型之間的關係和範圍,避免發生數據截斷。
  • 布爾值無法與其他數據類型進行轉換。

3.1 float與 int之間的轉換

需要注意float向int轉換時的精度損失。

// 這個就很簡單了
var a int64
a = 1
var b float64
b = 2.000

//a -- float64
c := float64(a)

// b -- int64
d := int64(b)

3.2 int 轉 string

  • 相當於byte或rune轉string
  • 如果int數值是ACSII碼的編號或者unicode字符集編號,轉成string本質就是根據字符集,將對應編碼的字符查找出來。
  • 如果int數值超出了unicode字符集編號範圍,則轉成的字符串顯示為亂碼。
  • 例如:19968轉string就是中文 “一”

【特別注意】

  • ASCII字符集中數字的10進制範圍是 [30-39]
  • ASCII字符集中大寫字母的10進制範圍是 [65-90]
  • ASCII字符集中小寫字母的10進制範圍是 [97-122]
  • Unicode字符集中漢字的範圍是[4e00-9fa5],10進制的範圍是[19968-40869]

3.3 stirng 轉 int

不允許將字符串轉int

4、常量

常量是一個簡單值的標識符,在程序運行時,不會被修改的量。

常量中的數據類型只可以是布爾型、數字型(整數型、浮點型和複數)和字符串型。

常量定義後未被使用不會在編譯時報錯。

常量的定義格式:

const identifier [type] = value

你可以省略類型說明符 [type],因為編譯器可以根據變量的值來推斷其類型。

  • 顯式類型定義: const b string = "abc"
  • 隱式類型定義: const b = "abc"
const c_name1, c_name2 = value1, value2

4.2 常量組(枚舉)

常量還可以用作枚舉:

const (
Unknown = 0
Female = 1
Male = 2
)

數字 0、1 和 2 分別代表未知性別、女性和男性。

常量可以用len(), cap(), unsafe.Sizeof()函數計算表達式的值。常量表達式中,函數必須是內置函數,否則編譯不過。

常量組中如果不指定類型和初始值,則與上一行非空常量的值相同。

const (
a = 10
b
c
)

// 此時 a b c的值均是 10

4.3 iota

iota,特殊常量,可以認為是一個可以被編譯器修改的常量。

iota 在 const關鍵字出現時將被重置為 0(const 內部的第一行之前),const 中每新增一行常量聲明將使 iota 計數一次(iota 可理解為 const 語句塊中的行索引)。

iota 可以被用作枚舉值:

const (
a = iota
b = iota
c = iota
)

第一個 iota 等於 0,每當 iota 在新的一行被使用時,它的值都會自動加 1;所以 a=0, b=1, c=2 可以簡寫為如下形式:

const (
a = iota
b
c
)

iota 用法

package main
import "fmt"
func main() {
const (
a = iota //0
b //1
c //2
d = "ha" //獨立值,iota += 1
e //"ha" iota += 1
f = 100 //iota +=1
g //100 iota +=1
h = iota //7,恢復計數
i //8
)
fmt.Println(a,b,c,d,e,f,g,h,i)
}

以上實例運行結果為:

0 1 2 ha ha 100 100 7 8 

再看個有趣的的 iota 實例:

package main
import "fmt"
const (
i=1<<iota> j=3<<iota> k
l
)
func main() {
fmt.Println("i=",i)
fmt.Println("j=",j)
fmt.Println("k=",k)
fmt.Println("l=",l)
}
/<iota>/<iota>

以上實例運行結果為:

i= 1
j= 6
k= 12
l= 24

iota 表示從 0 開始自動加 1,所以 i=1<<0, j=3<<1<< 表示左移的意思),即:i=1, j=6,這沒問題,關鍵在 k 和 l,從輸出結果看 k=3<<2l=3<<3

簡單描述下執行過程:

  • i=1
    :左移 0 位,不變仍為 1;
  • j=3:左移 1 位,變為二進制 110, 即 6;
  • k=3:左移 2 位,變為二進制 1100, 即 12;
  • l=3: 左移 3 位,變為二進制 11000,即 24。

這裡再次說明:常量組中如果不指定類型和初始值,則與上一行非空常量的值相同


分享到:


相關文章: