go语言基本数据类型

来源:互联网 发布:中国宇航出版社 知乎 编辑:程序博客网 时间:2024/05/22 14:36

初识GO语言

go是一门新语言,他在语言级提供了并发的支持(goroutine)和通信工具channel,同时它也是一门编译型、强类型的语言,拥有内存GC机制。程序的模块通过package来组织。

GO基础

整数

  • 十进制整数,使用0-9的数字表示且不以0开头。
  • 八进制整数,以0开头,0-7的数字表示
  • 十六进制整数,以0X或者是0x开头,0-9|A-F|a-f组成

  • 100 123455

  • 0100 0600
  • 0xff 0xFF12

浮点数

浮点数由整数部分、小数点和小数部分组成,整数部分和小数部分可以隐藏其中一种。也可以使用科学计数法表示:

  • 0.
  • 72.40
  • 072.40 和72.40一样
  • 2.71823
  • 1.e+0
  • 6.67428e-11
  • 1E6
  • .25
  • .12345E+5

复数的虚部

由一个整数或者是一个小数加上i表示

  • 0i
  • 011i //==11i 这里部分八进制了
  • 0.i
  • 2.71825i
  • 1.e+0i
  • 6.23423-11i
  • 1E6i
  • .25i
  • .1234E+5i

Rune literals

在go中,可以用一个rune(int32)类型来表示unicode的字符

string

string有两种表示形式

  • raw string,所有字符都以原始形式表示,不进行转移,回车输出的时候就是一个换行,不能表示本身

    this is string
    second line

  • 和C/C++一样的以双引号括起来的string,这种string表示基本和c/c++相同
    go的string支持unicode编码

类型

go支持命令类型和不具名类型,不具名类型主要针对于struct
boolean、numeric和string是语言内置类型;组合类型(array, struct, pointer, function, interface, slice, map, and channel types)可以通过type的语法来构成
任何一个类型T都有一个基本类型,如果一个类型T是一个内置类型或者是组合类型,其基本类型就是它本身,否则,T的基本类型是type声明的指向的类型

  • type T1 string 基本类型是string
  • type T2 T3 基本类型是string
  • type T3 []T1 基本类型是[]T1
  • type T4 T3 基本类型是[]T1

Method

一个类型可以拥有一个方法集合,一个interface的方法集合就是他的接口。一个类型的方法集合是通过声明一个函数且该函数拥有一个该类型的receiver,如下:
func (t T) funcname(param T1) {}
func表示funcname是一个函数,(t T)是函数的receiver,funcname是函数的名字,param是函数的参数。
指针类型*T的方法集合包含T的方法集合和receiver为*T的的方法
go语言中的通过一个类型实现了哪些函数来决定其实现了哪些接口,而不是通过直接的继承派生。

boolean type

一个boolean通过true和false来表示,其内置类型为bool

numeric types

数字类型包括整型和浮点型,内置的和系统无关的数字类型包括

  • uint8 8位无符号整型(0 to 255)
  • uint16 16位无符号整型(0 to 65535)
  • uint32 32位无符号整型(0 to 4294967295)
  • uint64 64位无符号整型(0 to 18446744073709551615)
  • int8 8位有符号整型(-128 to 127)
  • int16 16位有符号整型(-32768 to 32767)
  • int32 32位有符号整型(-2147483648 to 2147483647)
  • int64 64位有符号整型(-9223372036854775808 to 9223372036854775807)
  • float32 32位浮点类型
  • float64 64位浮点类型
  • complex32 由float32实部+虚部
  • complex64 由float64实部+虚部
  • byte uint8的别名
  • rune int32的别名
    平台相关的类型
  • uint,int 32或者是64位
  • uintptr 一个足够表示指针的无符号整数
    当不同类型进行混合运算的时候,需要进行明确的显示的类型转换

string

string是不可改变的,一旦创建,string的内容就不能被改变。
var a string = “this is a test”
a[1] = ‘a’ 非法,不能改变string的值
&a[i] 非法,不能对string的元素进行取地址
a[i]访问的是第i个byte len(i)是byte的个数,unicode可能占据多个byte
for , ch := range a {} 和 for , uni := range []rune(a) {} 可以遍历string的每一个unicode
for _, ch := range []byte(a) {}则可以遍历string的每一个byte

数组

数组是一个固定长度的类型的集合,长度是数组的len,类型是数组的element type。
index从0开始,数组可以是多维的

  • [32]byte
  • [2*N]struct {x, y int32} N必须是常量,这里结构体是一个匿名结构体
  • [1000]*float64
  • [2][3]int
  • [2][2][2]float64

slice

slice用于描述一个underlying array并且提供访问该数组元素的功能。未初始化的slice是nil。
因为数组是值类型,当进行函数参数传递的时候传递的是数组的拷贝,一是浪费空间;二是无法在函数内部修改array,所以可以使用具有同样element type的slice来进行参数传递,因为slice指向的是数组,所以通过slice则可以修改array。
slice通过make创建,make([]T, length, capacity)
其中第三个参数可以省略。
通过append可以向slice末尾添加新元素

var sli  = make([]byte, 0, 100)sli = append(sli, 10)

append返回一个新的slice,当append返回的新slice长度大于sli的capacity的时候,就会重新生成一个新的array,并让新的slice指向新的array。也就是append返回的新slice并不一定指向原来的array。

var a = [3]byte{}b := a[:]d := append(b, 1)d[1] = 'b'fmt.Println(a) //[0 0 0]fmt.Println(d) //[0 98 0 1]

slice和array一样,也支持多维slice,比如

  • []byte
  • []int
  • [][]int
    slice创建方式

  • var a = make([]int, 3,3) 通过make创建

  • var a = []int{} 一个空slice
  • var a = [3]int{}; b := a[:] 通过数组创建,此时b的underlying array就是a

struct

一个structfield组成,每一个field都由一个名字和类型组成。
field可以是具名和不具名的,non blank field必须是唯一的
struct {} 空结构体
struct{
x,y int
u float32
_ float32 //black field
A *[]int
f func()
}
不具名成员,也叫作嵌套成员,结构体将拥有嵌套成员的方法集合,具体规则如下:

  • 如果S包含匿名成员T,则S和*S都包含T的方法集合,*S还包含*T的方法集合
  • 如果S包含匿名成员*T,则S和*S都包含T和*T方法集合

struct {
T1
*T2
}
不具名成员的类型名将作为成员的名字,所以如下声明是错误的
struct{
T1
*T1
}
这样会造成成员的命名冲突
结构体的成员还可以包含一个可选的tag
struct {
T1 “任何字符串”
}
tag是结构体成员的属性,可以通过reflect查看。

pointer

指针可以指向任何类型,通过*+type声明

  • *int32
  • *[4]int
  • *[]byte

function

一个函数类型表所有的拥有同样的参数类型和返回值的类型的函数。
函数的参数列表中,参数名字必须要么全部都有,要么全部都没有,不能只有部分参数没有名字。
返回值列表同参数列表,当返回值列表拥有名字的时候,这些名字和参数名一样可以在函数体中使用。
参数支持可变参数列表,使用…T表示,可变参数必须在参数列表的最后面。
函数可以有多个返回值

  • func()
  • func(x int) int
  • func(a, _ int, z float32) bool
  • func(a int, b int32) (ret bool)
  • func (a int)(bool, int)
  • func (a, b int, c …int)

interface

一个接口类型指出了一个接口的方法集合,任何实现该方法集合的类型都实现了这个接口,并且可以赋值给该接口类型的变量。
type ReadWriter interface {
Read(b Buffer) bool
Write(b Buffer) bool
Close()
}
接口的方法名字不能重名,任何类型都可以实现一个接口,只要类型具有如下方法
func (p T) Read(b Buffer) bool {}
func (p T) Write(b Buffer) bool {}
func (p T) Close() {}
一个没有类型可以实现多个接口,只需要拥有接口对应的方法,比如所有类型都有实现了如下空接口。
interface{}
接口也支持嵌套,但是嵌套的接口不能拥有同名的方法

go
type T1 interface {
Read(b Buffer) bool
}
type T2 interface {
T1
Write(b buffer) bool
}
合法

go
type T2 interface {
T1
Read(b Buffer) bool
}
不合法
同时接口嵌套不能递归和自包含。

map

go的map是一个未排序的k-v集合,map[key type]element type
其中key type必须可以进行==和!=操作,因此key type不能使function、map或者slice。如果key是一个借口类型,则接口指向的实际类型必须支持==和!=

  • map[string]int
  • map[*T]struct{x, y float64}
  • map[string]interface{}

make(map[key]element, capacity)可以创建一个map

channel

channel提供了一个用于goroutine进行同行的机制,类似于linux的pipe,但是先并发安全的。
- chan int 双向channel
- chan<- int 只可以send的channel
- <-chan int 只可以receive的channel
channel可以是有缓冲或者没有缓冲的,通过make创建
make(chan int)创建一个没有缓冲的channel
make(chan int, 100)创建一个有100个缓冲的channel

当接收channel的时候,如果channel的缓冲区为空,则会阻塞当前goroutine,直到有新数据可取
发送的时候,如果chuannel的缓冲区满,阻塞当前goroutine,直到缓冲不满

0 0
原创粉丝点击