您好,登錄后才能下訂單哦!
這篇文章主要介紹“Go數據類型有哪些”,在日常操作中,相信很多人在Go數據類型有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Go數據類型有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
Go有四種數據類型:1、基礎類型,包括整數、浮點數、復數、布爾值、字符串、常量;2、聚合類型,包括數組、結構體(一種聚合的數據類型,是由零個或多個任意類型的值聚合成的實體。每個值稱為結構體的成員);3、引用類型,包括指針、slice、map、函數、通道;4、接口類型,是對其它類型行為的抽象和概括,是一種抽象的類型。
Go的數據類型一共分為四大類:基礎類型、聚合類型、引用類型和接口類型。
基礎類型分為:整數、浮點數、復數、布爾值、字符串、常量
聚合類型包括:數組、結構體
引用類型包括:指針、slice、map、函數、通道
接口類型
整數:
// 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
// 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
// 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
// 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
浮點數
// 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
// The complex built-in function constructs a complex value from two
// The complex built-in function constructs a complex value from two
// floating-point values. The real and imaginary parts must be of the same
// size, either float32 or float64 (or assignable to them), and the return
// value will be the corresponding complex type (complex64 for float32,
// complex128 for float64).
func complex(r, i FloatType) ComplexType
// The real built-in function returns the real part of the complex number c.
// The return value will be floating point type corresponding to the type of c.
func real(c ComplexType) FloatType
// The imag built-in function returns the imaginary part of the complex
// number c. The return value will be floating point type corresponding to
// the type of c.
func imag(c ComplexType) FloatType
布爾值
// 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.
)
字符串
// 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
常量
// 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.
數組和結構體是聚合類型;
它們的值由許多元素或成員字段的值組成。
數組是由同構的元素組成——每個數組元素都是完全相同的類型——結構體則是由異構的元素組成的。
數組和結構體都是有固定內存大小的數據結構。
相比之下,slice和map則是動態的數據結構,它們將根據需要動態增長。
數組
a := [2]int{1, 2}
b := [...]int{1, 2}
c := [2]int{1, 3}
fmt.Println(a == b, a == c, b == c) // "true false false"
d := [3]int{1, 2}
fmt.Println(a == d) // compile error: cannot compare [2]int == [3]int
如果一個數組的元素類型是可以相互比較的,那么數組類型也是可以相互比較的,這時候我們可以直接通過==比較運算符來比較兩個數組,只有當兩個數組的所有元素都是相等的時候數組才是相等的。不相等比較運算符!=遵循同樣的規則。
當調用一個函數的時候,函數的每個調用參數將會被賦值給函數內部的參數變量,所以函數參數變量接收的是一個復制的副本,并不是原始調用的變量。因為函數參數傳遞的機制導致傳遞大的數組類型將是低效的,并且對數組參數的任何的修改都是發生在復制的數組上,并不能直接修改調用時原始的數組變量。Call by value值傳遞
我們可以顯式地傳入一個數組指針,那樣的話函數通過指針對數組的任何修改都可以直接反饋到調用者
結構體
結構體是一種聚合的數據類型,是由零個或多個任意類型的值聚合成的實體。每個值稱為結構體的成員。
如果結構體成員名字是以大寫字母開頭的,那么該成員就是導出的;
1,
結構體值也可以用結構體面值表示,結構體面值可以指定每個成員的值。
type Point struct{ X, Y int }
p := Point{1, 2}
2,
以成員名字和相應的值來初始化,可以包含部分或全部的成員,
anim := gif.GIF{LoopCount: nframes}
在這種形式的結構體面值寫法中,如果成員被忽略的話將默認用零值。
3,
因為結構體通常通過指針處理,可以用下面的寫法來創建并初始化一個結構體變量,并返回結構體的地址:
pp := &Point{1, 2}
它是下面的語句是等價的
pp := new(Point)
*pp = Point{1, 2}
不過&Point{1, 2}寫法可以直接在表達式中使用,比如一個函數調用。
如果結構體的全部成員都是可以比較的,那么結構體也是可以比較的,那樣的話兩個結構體將可以使用或!=運算符進行比較。相等比較運算符將比較兩個結構體的每個成員,因此下面兩個比較的表達式是等價的:
type Point struct{ X, Y int }
p := Point{1, 2}
q := Point{2, 1}
fmt.Println(p.X == q.X && p.Y == q.Y) // "false"
fmt.Println(p == q) // "false"
指針
一個指針變量指向了一個值的內存地址。
var ip *int /* 指向整型*/ ip是一個指向int類型對象的 指針
var fp *float32 /* 指向浮點型 */ fp是一個指向float32類型對象的 指針
指針使用流程:
定義指針變量。
為指針變量賦值。
訪問指針變量中指向地址的值。
在指針類型前面加上 * 號(前綴)來獲取指針所指向的內容。
var a int= 20 /* 聲明實際變量 */
var ip *int /* 聲明指針變量 */
ip = &a /* 指針變量的存儲地址 */
fmt.Printf("a 變量的地址是: %x\n", &a )
/* 指針變量的存儲地址 */
fmt.Printf("ip 變量儲存的指針地址: %x\n", ip )
/* 使用指針訪問值 */
fmt.Printf("*ip 變量的值: %d\n", *ip )
slice
Slice(切片)代表變長的序列,序列中每個元素都有相同的類型。
一個slice類型一般寫作[]T,其中T代表slice中元素的類型;
slice的語法和數組很像,只是沒有固定長度而已
type slice struct {
array unsafe.Pointer
len int
cap int
}
多個slice可以復用同一個底層數組
// The len built-in function returns the length of v, according to its type:
// Array: the number of elements in v.
// Pointer to array: the number of elements in *v (even if v is nil).
// Slice, or map: the number of elements in v; if v is nil, len(v) is zero.
// String: the number of bytes in v.
// Channel: the number of elements queued (unread) in the channel buffer;
// if v is nil, len(v) is zero.
// For some arguments, such as a string literal or a simple array expression, the
// result can be a constant. See the Go language specification's "Length and
// capacity" section for details.
func len(v Type) int
// The cap built-in function returns the capacity of v, according to its type:
// Array: the number of elements in v (same as len(v)).
// Pointer to array: the number of elements in *v (same as len(v)).
// Slice: the maximum length the slice can reach when resliced;
// if v is nil, cap(v) is zero.
// Channel: the channel buffer capacity, in units of elements;
// if v is nil, cap(v) is zero.
// For some arguments, such as a simple array expression, the result can be a
// constant. See the Go language specification's "Length and capacity" section for
// details.
func cap(v Type) int
// The append built-in function appends elements to the end of a slice. If
// it has sufficient capacity, the destination is resliced to accommodate the
// new elements. If it does not, a new underlying array will be allocated.
// Append returns the updated slice. It is therefore necessary to store the
// result of append, often in the variable holding the slice itself:
// slice = append(slice, elem1, elem2)
// slice = append(slice, anotherSlice...)
// As a special case, it is legal to append a string to a byte slice, like this:
// slice = append([]byte("hello "), "world"...)
func append(slice []Type, elems ...Type) []Type
// The make built-in function allocates and initializes an object of type
// slice, map, or chan (only). Like new, the first argument is a type, not a
// value. Unlike new, make's return type is the same as the type of its
// argument, not a pointer to it. The specification of the result depends on
// the type:
// Slice: The size specifies the length. The capacity of the slice is
// equal to its length. A second integer argument may be provided to
// specify a different capacity; it must be no smaller than the
// length. For example, make([]int, 0, 10) allocates an underlying array
// of size 10 and returns a slice of length 0 and capacity 10 that is
// backed by this underlying array.
// Map: An empty map is allocated with enough space to hold the
// specified number of elements. The size may be omitted, in which case
// a small starting size is allocated.
// Channel: The channel's buffer is initialized with the specified
// buffer capacity. If zero, or the size is omitted, the channel is
// unbuffered.
func make(t Type, size ...IntegerType) Type
// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type
// The copy built-in function copies elements from a source slice into a
// destination slice. (As a special case, it also will copy bytes from a
// string to a slice of bytes.) The source and destination may overlap. Copy
// returns the number of elements copied, which will be the minimum of
// len(src) and len(dst).
func copy(dst, src []Type) int
// The delete built-in function deletes the element with the specified key
// (m[key]) from the map. If m is nil or there is no such element, delete
// is a no-op.
func delete(m map[Type]Type1, key Type)
map
在Go語言中,一個map就是一個哈希表的引用,map類型可以寫為map[K]V,其中K和V分別對應key和value。map中所有的key都有相同的類型,所有的value也有著相同的類型。
其中K對應的key必須是支持==比較運算符的數據類型,所以map可以通過測試key是否相等來判斷是否已經存在。雖然浮點數類型也是支持相等運算符比較的,但是將浮點數用做key類型則是一個壞的想法。
對于V對應的value數據類型則沒有任何的限制。
創建map:
1,
內置的make函數可以創建一個map:
ages := make(map[string]int) // mapping from strings to ints
2,
我們也可以用map字面值的語法創建map,同時還可以指定一些最初的key/value:
ages := map[string]int{
"alice": 31,
"charlie": 34,
}
這相當于
ages := make(map[string]int)
ages["alice"] = 31
ages["charlie"] = 34
因此,另一種創建空的map的表達式是map[string]int{}。
Map中的元素通過key對應的下標語法訪問:
ages["alice"] = 32
delete(ages, "alice") // remove element ages["alice"]
所有這些操作是安全的,即使這些元素不在map中也沒有關系;
如果一個查找失敗將返回value類型對應的零值,例如,
即使map中不存在“bob”下面的代碼也可以正常工作,因為ages["bob"]失敗時將返回0。
ages["bob"] = ages["bob"] + 1 // happy birthday!
遍歷map
for name, age := range ages {
fmt.Printf("%s\t%d\n", name, age)
}
函數
函數聲明包括函數名、形式參數列表、返回值列表(可省略)以及函數體。
func name(parameter-list) (result-list) {
body
}
channel 通道
如果說goroutine是Go語音程序的并發體的話,那么channels它們之間的通信機制。
一個channels是一個通信機制,它可以讓一個goroutine通過它給另一個goroutine發送值信息。
每個channel都有一個特殊的類型,也就是channels可發送數據的類型。一個可以發送int類型數據的channel一般寫為chan int。
使用內置的make函數,我們可以創建一個channel:
使用內置的make函數,我們可以創建一個channel:
ch := make(chan int) // ch has type 'chan int'
和map類似,channel也一個對應make創建的底層數據結構的引用。
當我們復制一個channel或用于函數參數傳遞時,我們只是拷貝了一個channel引用,因此調用者何被調用者將引用同一個channel對象。和其它的引用類型一樣,channel的零值也是nil。
兩個相同類型的channel可以使用==運算符比較。如果兩個channel引用的是相通的對象,那么比較的結果為真。一個channel也可以和nil進行比較。
接口
接口類型是對其它類型行為的抽象和概括;因為接口類型不會和特定的實現細節綁定在一起,通過這種抽象的方式我們可以讓我們的函數更加靈活和更具有適應能力。
很多面向對象的語言都有相似的接口概念,但Go語言中接口類型的獨特之處在于它是滿足隱式實現的。
也就是說,我們沒有必要對于給定的具體類型定義所有滿足的接口類型;簡單地擁有一些必需的方法就足夠了。
這種設計可以讓你創建一個新的接口類型滿足已經存在的具體類型卻不會去改變這些類型的定義;當我們使用的類型來自于不受我們控制的包時這種設計尤其有用。
接口類型是一種抽象的類型。它不會暴露出它所代表的對象的內部值的結構和這個對象支持的基礎操作的集合;它們只會展示出它們自己的方法。也就是說當你有看到一個接口類型的值時,你不知道它是什么,唯一知道的就是可以通過它的方法來做什么。
到此,關于“Go數據類型有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。