大家好,我又來了,接著上一期我們搭建了golang的環境變數後,我們接著看一下程式設計的基礎常識。
眾所周知在程式設計中,我們涉及到一下常用的東西:
- 資料型別
- 變數和常量
- 運算子
- 語句
- 陣列、集合
- 方法
- 資源引入
- 包
1、資料型別
在go語言中,我們常見的資料型別有很多,但是值得注意的是,他們都是小寫!都是小寫!都是小寫!
package builtin
// bool is the set of boolean values, true and false.
type bool bool
// true and false are the two untyped boolean values.
const (
true = 0 == 0 // Untyped bool.
false = 0 != 0 // Untyped bool.
)
// uint8 is the set of all unsigned 8-bit integers.
// Range: 0 through 255.
type uint8 uint8
// uint16 is the set of all unsigned 16-bit integers.
// Range: 0 through 65535.
type uint16 uint16
// uint32 is the set of all unsigned 32-bit integers.
// Range: 0 through 4294967295.
type uint32 uint32
// uint64 is the set of all unsigned 64-bit integers.
// Range: 0 through 18446744073709551615.
type uint64 uint64
// int8 is the set of all signed 8-bit integers.
// Range: -128 through 127.
type int8 int8
// int16 is the set of all signed 16-bit integers.
// Range: -32768 through 32767.
type int16 int16
// int32 is the set of all signed 32-bit integers.
// Range: -2147483648 through 2147483647.
type int32 int32
// int64 is the set of all signed 64-bit integers.
// Range: -9223372036854775808 through 9223372036854775807.
type int64 int64
// float32 is the set of all IEEE-754 32-bit floating-point numbers.
type float32 float32
// float64 is the set of all IEEE-754 64-bit floating-point numbers.
type float64 float64
// complex64 is the set of all complex numbers with float32 real and
// imaginary parts.
type complex64 complex64
// complex128 is the set of all complex numbers with float64 real and
// imaginary parts.
type complex128 complex128
// string is the set of all strings of 8-bit bytes, conventionally but not
// necessarily representing UTF-8-encoded text. A string may be empty, but
// not nil. Values of string type are immutable.
type string string
// int is a signed integer type that is at least 32 bits in size. It is a
// distinct type, however, and not an alias for, say, int32.
type int int
// uint is an unsigned integer type that is at least 32 bits in size. It is a
// distinct type, however, and not an alias for, say, uint32.
type uint uint
// uintptr is an integer type that is large enough to hold the bit pattern of
// any pointer.
type uintptr uintptr
// byte is an alias for uint8 and is equivalent to uint8 in all ways. It is
// used, by convention, to distinguish byte values from 8-bit unsigned
// integer values.
type byte = uint8
// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.
type rune = int32
// iota is a predeclared identifier representing the untyped integer ordinal
// number of the current const specification in a (usually parenthesized)
// const declaration. It is zero-indexed.
const iota = 0 // Untyped int.
// nil is a predeclared identifier representing the zero value for a
// pointer, channel, func, interface, map, or slice type.
var nil Type // Type must be a pointer, channel, func, interface, map, or slice type
// Type is here for the purposes of documentation only. It is a stand-in
// for any Go type, but represents the same type for any given function
// invocation.
type Type int
// Type1 is here for the purposes of documentation only. It is a stand-in
// for any Go type, but represents the same type for any given function
// invocation.
type Type1 int
// IntegerType is here for the purposes of documentation only. It is a stand-in
// for any integer type: int, uint, int8 etc.
type IntegerType int
// FloatType is here for the purposes of documentation only. It is a stand-in
// for either float type: float32 or float64.
type FloatType float32
// ComplexType is here for the purposes of documentation only. It is a
// stand-in for either complex type: complex64 or complex128.
type ComplexType complex64
複製程式碼
在上面的原始碼摘錄中,我們可以看到go語言完整的資料型別。但是,我們總結下常用的如下:
- int、uint 整形、無符號整形
- int8、int16(2位元組,-32768~32767)、int32(rune)、int64
- uint8、uint16(2位元組,0~65535)、uint32、uint64
- string 字串(原生utf-8編碼支援)
- bool 布林型
- float 浮點型
- float32、float64 (4/8位元組,精確到小數後7/15位)
- byte 1位元組 uint8的別名
- nil 空型別
- complex64、complex128 複數型別(實數、虛數),8位元組、16位元組
- uintptr 足夠大的位模式儲存指標的整數型別(uintptr is an integer type that is large enough to hold the bit pattern of any pointer.)
同樣的,還有一些派生資料型別(我個人喜歡稱之為擴充套件資料型別或者是包裝資料型別),基本如下:
- 指標型別(Pointer)
- 陣列型別
- 結構化型別(struct)
- Channel 型別
- 函式型別
- 切片型別
- 介面型別(interface)
- map型別
當然這些擴充套件資料型別我們將在以後一一闡述。
go 1.9版本對於數字型別,無需定義int及float,系統會自動識別。
附贈demo小案例(完成變數的申明和使用,以及注意事項)
package main
//導包
import "fmt"
//分組申明變數
var (
personA = "小王"
personC = "小張"
ageA = 18
)
func main() {
//快捷申明變數 省卻var識別符號
mName := "程先生"
//var 標明資料是變數
var mSex = "漢子"
fmt.Println(mName + ",哎喲我去,你是" + mSex)
var a = 1.5
var b = 2
fmt.Println(a, " ====我是分隔符==== ", b)
fmt.Println(personA, " ====我是分隔符==== ", personC, " ====我是分隔符==== ", ageA)
}
複製程式碼
當然,執行結果如下:
程先生,哎喲我去,你是漢子
1.5 ====我是分隔符==== 2
小王 ====我是分隔符==== 小張 ====我是分隔符==== 18
複製程式碼
在上面的程式碼中,有下面一些操作
- 必須申明包,且主程式包為:main
- 入口函式為:main,且沒有任何引數
- var為變數申明識別符號
- 變數可以分組申明(導包可以分組嗎?)
- 可以採用快捷申明變數 := ,注意:僅僅能在函式中使用
- 變數的基本資料型別無需申明,系統會自動推導
- 當然手動申明變數型別如: var aa string = "餈粑"
- 所有的變數都是使用過的(未使用的變數會產生編譯異常)
- java中輸出語句基本資料型別和string可以通過“+”連線,但是go中不允許這種騷操作
- 變數可以即時申請
- 無需“;”結尾,換行既是語句的結束
- 雖然允許多變數一行賦值,但是不推薦如此做,所以也未舉例
常量
常量是一個簡單值的識別符號,在程式執行時,不會被修改的量。 常量中的資料型別只可以是布林型、數字型(整數型、浮點型和複數)和字串型。
常量定義格式: const identifier [type] = value
如下:
- 顯式型別定義: const b string = "abc"
- 隱式型別定義: const b = "abc"
- 多個相同型別的宣告可以簡寫為: const c_name1, c_name2 = value1, value2 (當然,我一樣不推薦這樣定義,降低了可讀性)
那麼我們試一試小demo
//在main方法中執行下面程式碼段
const PI = 3.14
r := 4
fmt.Println("圓的面積為:", PI*r*r)
複製程式碼
在我們執行後程式碼報錯如下:
# command-line-arguments
./demo001.go:26:38: constant 3.14 truncated to integer
複製程式碼
上面程式碼提示PI被截斷為整數,但是程式卻沒能成功執行,是不是go不支援資料型別自動轉換呢?
我們這時候考慮一下把常量顯示申明為float32試一試:
const PI float32 = 3.14
r := 4
fmt.Println("圓的面積為:", PI*r*r)
複製程式碼
這次更加悽慘,程式碼甚至不能通過編譯,在“PI *r *r”這裡提示型別匹配錯誤!emmmm····
我們只能選擇把r申明為float試試,如下:
const PI = 3.14
r := 4.0
fmt.Println("圓的面積為:", PI*r*r)
複製程式碼
恭喜,本次編譯通過,且有輸出內容,如下:
圓的面積為: 50.24
複製程式碼
當然如下程式碼也能成功執行:
const PI float32 = 3.14
var r float32 = 4.0
fmt.Println("圓的面積為:", PI*r*r)
複製程式碼
這說明,go是一個嚴格強調資料型別匹配的語言。
當然,前面我們看到變數分組申明,那麼這裡我們常量一樣可以分組申明:
const (
OK = 0
ERROR = 1
EMPUTY = -1
)
複製程式碼
常量申明中的 iota
ota,特殊常量,可以認為是一個可以被編譯器修改的常量。 在每一個const關鍵字出現時,被重置為0,然後再下一個const出現之前,每出現一次iota,其所代表的數字會自動增加1。
我們來列舉一些常量:
const (
a = iota
b = iota
c = iota
)
//第一個 iota 等於 0,每當 iota 在新的一行被使用時,它的值都會自動加 1;所以 a=0, b=1, c=2 可以簡寫為如下形式:
const (
a = iota
b
c
)
複製程式碼
當然我們也可以看看別人教程(菜鳥教程-> Go語言常量)所書寫的例子:
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 (
//第一個iota預設值是0,左移位1,則不變
i=1<<iota
//左移位 0+1,3的二進位制是0011,左移位一次就是0110,十進位制結果為6
j=3<<iota
//這裡實際程式碼是: k = 3 << iota ,按照上面的推算則是左移位1+1,下面的l同理
k
l
)
func main() {
fmt.Println("i=",i)
fmt.Println("j=",j)
fmt.Println("k=",k)
fmt.Println("l=",l)
}
複製程式碼
輸出結果:
i= 1
j= 6
k= 12
l= 24
複製程式碼
總結
變數的申明:
- var name [type] = value
- 方法內 name := value
- 變數組申明 var (name = value)
常量的申明:
- const name [type] = value
- 常量組申明:const (name = value)
其他:
- 內建函式
- 變數常量資料型別自推導
- 嚴格的資料型別限制