首頁  >  文章  >  後端開發  >  Go有幾種資料類型

Go有幾種資料類型

青灯夜游
青灯夜游原創
2023-01-10 14:38:222343瀏覽

Go有四種資料類型:1、基礎類型,包括整數、浮點數、複數、布林值、字串、常數;2、聚合類型,包括陣列、結構體(一種聚合的數據類型,是由零個或多個任意類型的值聚合成的實體。每個值稱為結構體的成員);3、引用類型,包括指標、slice、map、函數、通道;4、介面類型,是對其它類型行為的抽象與概括,是一種抽象的類型。

Go有幾種資料類型

本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

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

Go有幾種資料類型

#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视频教程编程教学

以上是Go有幾種資料類型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn